V10/lbin/libjobs/sigset.c

Compare this file to the similar file:
Show the results in this format:

#include <signal.h>
#include <errno.h>
/*
 * signal system call interface package.
 */
extern	errno;

#ifdef PDP11
#define BYTESPERVEC	4		/* size of machine language vector */
extern	char	mvectors[NSIG+1][BYTESPERVEC];
#endif

static	int (*cactions[NSIG+1])();	/* saved callers signal actions */
static	char setflg[NSIG+1];		/* =1 means action perm ``sigset'' */
int	(*sigsys())();
int	_sigcatch();

/*
 * old signal protocol.  when signal occurs, further
 * instances of same signal are not blocked, so that
 * recursive signals are possible.  the action will
 * not be re-enabled by these routines when return
 * is made from the interrupt (compare sigset).
 */
int (*
signal(signum, action))()
register int signum;
register int (*action)();
{
	register int (*retval)();

	if (signum <= 0 || signum > NSIG) {
		errno = EINVAL;
		return (BADSIG);
	}
	retval = cactions[signum];
	cactions[signum] = action;
	if (action != SIG_IGN && action != SIG_DFL && action != SIG_HOLD)
		if (SIGISDEFER(action))
#ifdef PDP11
			action = DEFERSIG(mvectors[signum]);
		else
			action = (int (*)())(int)mvectors[signum];
#else
			action = DEFERSIG(_sigcatch);
		else
			action = _sigcatch;
#endif
	action = sigsys(signum, action);
	if (action == SIG_IGN || action == SIG_DFL || action == SIG_HOLD)
		retval = action;
	setflg[signum] = 0;	/* 'tis fleeting (madness may take its toll) */
	return (retval);
}

/*
 * set ``permanent'' action for this signal.  if a function,
 * it will be deferred when interupt occurs and enabled again
 * when return occurs.  after sigset, sighold and sigrelse can
 * be used to protect signum signal critical sections.
 */
int (*
sigset(signum, action))()
register int signum;
register int (*action)();
{
	register int (*retval)();

	if (signum <= 0 || signum > NSIG) {
		errno = EINVAL;
		return (BADSIG);
	}
	retval = cactions[signum];
	cactions[signum] = action;
	if (action != SIG_IGN && action != SIG_DFL && action != SIG_HOLD)
		action = DEFERSIG(_sigcatch);
	action = sigsys(signum, action);
	if (action == SIG_IGN || action == SIG_DFL || action == SIG_HOLD)
		retval = action;
	setflg[signum] = 1;		/* don't want to lose control! */
	return (retval);
}

/*
 * temporarily hold a signal until further notice
 * via sigpause or sigrelse
 */
sighold(signum)
register int signum;
{

	if (signum <= 0 || signum > NSIG) {
		errno = EINVAL;
		return;
	}
	sigsys(signum, SIG_HOLD);
}

/*
 * atomically release the signal and pause
 * if no signals pending.  signal will normally
 * be held on return (unless an routine called at
 * interrupt time resets it).
 */
sigpause(signum)
register signum;
{

	if (signum <= 0 || signum > NSIG || setflg[signum] == 0) {
		errno = EINVAL;
		return;
	}
#ifdef PDP11
	sigsys(signum|SIGDOPAUSE, DEFERSIG(mvectors[signum]));
#else
	sigsys(signum|SIGDOPAUSE, DEFERSIG(_sigcatch));
#endif
}

/*
 * re-enable signals after sighold or possibly after sigpause
 */
sigrelse(signum)
register signum;
{
	if (signum <= 0 || signum > NSIG || setflg[signum] == 0) {
		errno = EINVAL;
		return (-1);
	}
#ifdef PDP11
	sigsys(signum, DEFERSIG(mvectors[signum]));
#else
	sigsys(signum, DEFERSIG(_sigcatch));
#endif
	return (0);
}

/*
 * ignore signal
 */
sigignore(signum)
int signum;
{

	sigsys(signum, SIG_IGN);
}

#ifdef PDP11
/*
 * called at interrupt time.  on pdp11 assembly language
 * routine resets signal catch to returned action, if
 * returned action is not SIG_DFL.
 */
int (*
_sigcatch(signum))()
register signum;
{

	(*cactions[signum])(signum);		/* call the C routine */
	if (setflg[signum])
		return (DEFERSIG(mvectors[signum]);
	else
		return (SIG_DFL);		/* old protocol */
}
#else
/*
 * called at interrupt time.  on vax, sigpeel will peel
 * off the interrupt frames and reenable the signal with
 * the argument action (cleanly).  if the action is
 * SIG_DFL sigpeel will do nothing, but we can as well
 * return ourselves without its help.
 */
_sigcatch(signum, code)
register signum;
int code;
{

	(*cactions[signum])(signum);
	if (setflg[signum]) {
		sigpeel(signum, DEFERSIG(_sigcatch));
		/*NOTREACHED*/
	}
	/* old protocol, just return */
}
#endif