summaryrefslogtreecommitdiffstats
path: root/contrib/tcsh/tc.sig.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcsh/tc.sig.c')
-rw-r--r--contrib/tcsh/tc.sig.c407
1 files changed, 69 insertions, 338 deletions
diff --git a/contrib/tcsh/tc.sig.c b/contrib/tcsh/tc.sig.c
index 95838b3..343754f 100644
--- a/contrib/tcsh/tc.sig.c
+++ b/contrib/tcsh/tc.sig.c
@@ -1,4 +1,4 @@
-/* $Header: /src/pub/tcsh/tc.sig.c,v 3.29 2005/01/18 20:24:51 christos Exp $ */
+/* $Header: /p/tcsh/cvsroot/tcsh/tc.sig.c,v 3.36 2006/08/24 20:56:31 christos Exp $ */
/*
* tc.sig.c: Signal routine emulations
*/
@@ -32,377 +32,108 @@
*/
#include "sh.h"
-RCSID("$Id: tc.sig.c,v 3.29 2005/01/18 20:24:51 christos Exp $")
+RCSID("$tcsh: tc.sig.c,v 3.36 2006/08/24 20:56:31 christos Exp $")
#include "tc.wait.h"
-#ifndef BSDSIGS
-
-/* this stack is used to queue signals
- * we can handle up to MAX_CHLD outstanding children now;
- */
-#define MAX_CHLD 50
-
-# ifdef UNRELSIGS
-static struct mysigstack {
- int s_w; /* wait report */
- int s_errno; /* errno returned; */
- pid_t s_pid; /* pid returned */
-} stk[MAX_CHLD];
-static int stk_ptr = -1;
-
-
-/* queue child signals
- */
-static RETSIGTYPE
-sig_ch_queue()
-{
-# ifdef JOBDEBUG
- xprintf("queue SIGCHLD\n");
- flush();
-# endif /* JOBDEBUG */
- stk_ptr++;
- stk[stk_ptr].s_pid = (pid_t) wait(&stk[stk_ptr].s_w);
- stk[stk_ptr].s_errno = errno;
- (void) signal(SIGCHLD, sig_ch_queue);
-}
-
-/* process all awaiting child signals
- */
-static RETSIGTYPE
-sig_ch_rel()
-{
- while (stk_ptr > -1)
- pchild(SIGCHLD);
-# ifdef JOBDEBUG
- xprintf("signal(SIGCHLD, pchild);\n");
-# endif /* JOBDEBUG */
- (void) signal(SIGCHLD, pchild);
-}
-
-
-/* libc.a contains these functions in SYSVREL >= 3. */
-RETSIGTYPE
-(*xsigset(a, b)) ()
- int a;
- signalfun_t b;
-{
- return (signal(a, b));
-}
-
-/* release signal
- * release all queued signals and
- * set the default signal handler
- */
-void
-sigrelse(what)
- int what;
-{
- if (what == SIGCHLD)
- sig_ch_rel();
-
-# ifdef COHERENT
- (void) signal(what, what == SIGINT ? pintr : SIG_DFL);
-# endif /* COHERENT */
-}
-
-/* hold signal
- * only works with child and interrupt
- */
void
-xsighold(what)
- int what;
-{
- if (what == SIGCHLD)
- (void) signal(SIGCHLD, sig_ch_queue);
-
-# ifdef COHERENT
- (void) signal(what, SIG_IGN);
-# endif /* COHERENT */
+sigset_interrupting(int sig, void (*fn) (int))
+{
+ struct sigaction act;
+
+ act.sa_handler = fn;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ if (sigaction(sig, &act, NULL) == 0) {
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, sig);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ }
}
-/* ignore signal
- */
-void
-xsigignore(a)
- int a;
-{
- (void) signal(a, SIG_IGN);
-}
+static volatile sig_atomic_t alrmcatch_pending; /* = 0; */
+static volatile sig_atomic_t pchild_pending; /* = 0; */
+static volatile sig_atomic_t phup_pending; /* = 0; */
+static volatile sig_atomic_t pintr_pending; /* = 0; */
+int alrmcatch_disabled; /* = 0; */
+int phup_disabled; /* = 0; */
+int pchild_disabled; /* = 0; */
+int pintr_disabled; /* = 0; */
-/* atomically release one signal
- */
void
-xsigpause(what)
- int what;
-{
- /* From: Jim Mattson <mattson%cs@ucsd.edu> */
- if (what == SIGCHLD)
- pchild(SIGCHLD);
-}
-
-
-/* return either awaiting processes or do a wait now
- */
-pid_t
-ourwait(w)
- int *w;
+handle_pending_signals(void)
{
- pid_t pid;
-
-# ifdef JOBDEBUG
- xprintf(CGETS(25, 1, "our wait %d\n"), stk_ptr);
- flush();
-# endif /* JOBDEBUG */
-
- if (stk_ptr == -1) {
- /* stack empty return signal from stack */
- pid = (pid_t) wait(w);
-# ifdef JOBDEBUG
- xprintf("signal(SIGCHLD, pchild);\n");
-# endif /* JOBDEBUG */
- (void) signal(SIGCHLD, pchild);
- return (pid);
+ if (!phup_disabled && phup_pending) {
+ phup_pending = 0;
+ phup();
}
- else {
- /* return signal from stack */
- errno = stk[stk_ptr].s_errno;
- *w = stk[stk_ptr].s_w;
- stk_ptr--;
- return (stk[stk_ptr + 1].s_pid);
+ if (!pintr_disabled && pintr_pending) {
+ pintr_pending = 0;
+ pintr();
+ }
+ if (!pchild_disabled && pchild_pending) {
+ pchild_pending = 0;
+ pchild();
+ }
+ if (!alrmcatch_disabled && alrmcatch_pending) {
+ alrmcatch_pending = 0;
+ alrmcatch();
}
-} /* end ourwait */
-
-# ifdef COHERENT
-# undef signal
-RETSIGTYPE
-(*xsignal(a, b)) ()
- int a;
- signalfun_t b;
-{
- if (a == SIGCHLD)
- return SIG_DFL;
- else
- return (signal(a, b));
}
-# endif /* COHERENT */
-# endif /* UNRELSIGS */
-
-# ifdef SXA
-/*
- * SX/A is SYSVREL3 but does not have sys5-sigpause().
- * I've heard that sigpause() is not defined in SYSVREL3.
- */
-/* This is not need if you make tcsh by BSD option's cc. */
void
-sigpause(what)
+queue_alrmcatch(int sig)
{
- if (what == SIGCHLD) {
- (void) bsd_sigpause(bsd_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
- }
- else if (what == 0) {
- pause();
- }
- else {
- xprintf("sigpause(%d)\n", what);
- pause();
- }
+ USE(sig);
+ alrmcatch_pending = 1;
}
-# endif /* SXA */
-#endif /* !BSDSIGS */
-
-#ifdef NEEDsignal
-/* turn into bsd signals */
-RETSIGTYPE
-(*xsignal(s, a)) ()
- int s;
- signalfun_t a;
+void
+queue_pchild(int sig)
{
- sigvec_t osv, sv;
-
- (void) mysigvec(s, NULL, &osv);
- sv = osv;
- sv.sv_handler = a;
-#ifdef SIG_STK
- sv.sv_onstack = SIG_STK;
-#endif /* SIG_STK */
-#ifdef SV_BSDSIG
- sv.sv_flags = SV_BSDSIG;
-#endif /* SV_BSDSIG */
-
- if (mysigvec(s, &sv, NULL) < 0)
- return (BADSIG);
- return (osv.sv_handler);
+ USE(sig);
+ pchild_pending = 1;
}
-#endif /* NEEDsignal */
-
-#ifdef POSIXSIGS
-/*
- * Support for signals.
- */
-
-extern int errno;
-
-/* Set and test a bit. Bits numbered 1 to 32 */
-
-#define SETBIT(x, y) x |= sigmask(y)
-#define ISSET(x, y) ((x & sigmask(y)) != 0)
-
-#ifdef DEBUG
-# define SHOW_SIGNALS 1 /* to assist in debugging signals */
-#endif /* DEBUG */
-
-#ifdef SHOW_SIGNALS
-char *show_sig_mask();
-#endif /* SHOW_SIGNALS */
-
-#ifndef __PARAGON__
-/*
- * sigsetmask(mask)
- *
- * Set a new signal mask. Return old mask.
- */
-sigmask_t
-sigsetmask(mask)
- sigmask_t mask;
+void
+queue_phup(int sig)
{
- sigset_t set, oset;
- int m;
- int i;
-
- (void) sigemptyset(&set);
- (void) sigemptyset(&oset);
-
- for (i = 1; i <= MAXSIG; i++)
- if (ISSET(mask, i))
- (void) sigaddset(&set, i);
-
- if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1) {
- xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
- mask, errno);
- }
-
- m = 0;
- for (i = 1; i <= MAXSIG; i++)
- if (sigismember(&oset, i) == 1)
- SETBIT(m, i);
-
- return (m);
+ USE(sig);
+ phup_pending = 1;
}
-#endif /* __PARAGON__ */
-#ifndef __DGUX__
-/*
- * sigblock(mask)
- *
- * Add "mask" set of signals to the present signal mask.
- * Return old mask.
- */
-sigmask_t
-sigblock(mask)
- sigmask_t mask;
+void
+queue_pintr(int sig)
{
- sigset_t set, oset;
- int m;
- int i;
-
- (void) sigemptyset(&set);
- (void) sigemptyset(&oset);
-
- /* Get present set of signals. */
- if ((sigprocmask(SIG_SETMASK, NULL, &set)) == -1)
- stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
-
- /* Add in signals from mask. */
- for (i = 1; i <= MAXSIG; i++)
- if (ISSET(mask, i))
- (void) sigaddset(&set, i);
-
- if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1)
- stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
-
- /* Return old mask to user. */
- m = 0;
- for (i = 1; i <= MAXSIG; i++)
- if (sigismember(&oset, i) == 1)
- SETBIT(m, i);
-
- return (m);
+ USE(sig);
+ pintr_pending = 1;
}
-#endif /* __DGUX__ */
-
-/*
- * bsd_sigpause(mask)
- *
- * Set new signal mask and wait for signal;
- * Old mask is restored on signal.
- */
void
-bsd_sigpause(mask)
- sigmask_t mask;
+disabled_cleanup(void *xdisabled)
{
- sigset_t set;
- int i;
+ int *disabled;
- (void) sigemptyset(&set);
-
- for (i = 1; i <= MAXSIG; i++)
- if (ISSET(mask, i))
- (void) sigaddset(&set, i);
- (void) sigsuspend(&set);
+ disabled = xdisabled;
+ if (--*disabled == 0)
+ handle_pending_signals();
}
-/*
- * bsd_signal(sig, func)
- *
- * Emulate bsd style signal()
- */
-RETSIGTYPE (*bsd_signal(sig, func)) ()
- int sig;
- signalfun_t func;
+void
+pintr_disabled_restore(void *xold)
{
- struct sigaction act, oact;
- sigset_t set;
- signalfun_t r_func;
-
- if (sig < 0 || sig > MAXSIG) {
- xprintf(CGETS(25, 2,
- "error: bsd_signal(%d) signal out of range\n"), sig);
- return((signalfun_t) SIG_IGN);
- }
+ int *old;
- (void) sigemptyset(&set);
-
- act.sa_handler = (signalfun_t) func; /* user function */
- act.sa_mask = set; /* signal mask */
- act.sa_flags = 0; /* no special actions */
-
- if (sigaction(sig, &act, &oact)) {
- xprintf(CGETS(25, 3,
- "error: bsd_signal(%d) - sigaction failed, errno %d\n"),
- sig, errno);
- return((signalfun_t) SIG_IGN);
- }
-
- r_func = (signalfun_t) oact.sa_handler;
- return(r_func);
+ old = xold;
+ pintr_disabled = *old;
}
-#endif /* POSIXSIG */
-
-#ifdef SIGSYNCH
-static long Synch_Cnt = 0;
-
-RETSIGTYPE
-synch_handler(sno)
-int sno;
+void
+pintr_push_enable(int *saved)
{
- if (sno != SIGSYNCH)
- abort();
- Synch_Cnt++;
+ *saved = pintr_disabled;
+ pintr_disabled = 0;
+ cleanup_push(saved, pintr_disabled_restore);
+ handle_pending_signals();
}
-#endif /* SIGSYNCH */
OpenPOWER on IntegriCloud