+#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