summaryrefslogtreecommitdiffstats
path: root/contrib/tcsh/tc.sig.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2000-04-15 04:41:27 +0000
committerobrien <obrien@FreeBSD.org>2000-04-15 04:41:27 +0000
commit4ad28cefef28ce6bdb44a0532cfe20a2076bc694 (patch)
tree7679c440a91912ee9586cee3ebab24596c0fe1c4 /contrib/tcsh/tc.sig.c
downloadFreeBSD-src-4ad28cefef28ce6bdb44a0532cfe20a2076bc694.zip
FreeBSD-src-4ad28cefef28ce6bdb44a0532cfe20a2076bc694.tar.gz
Import the latest version of the 44BSD C-shell -- tcsh-6.09.
Diffstat (limited to 'contrib/tcsh/tc.sig.c')
-rw-r--r--contrib/tcsh/tc.sig.c418
1 files changed, 418 insertions, 0 deletions
diff --git a/contrib/tcsh/tc.sig.c b/contrib/tcsh/tc.sig.c
new file mode 100644
index 0000000..f7feae8
--- /dev/null
+++ b/contrib/tcsh/tc.sig.c
@@ -0,0 +1,418 @@
+/* $Header: /src/pub/tcsh/tc.sig.c,v 3.24 1998/04/08 17:57:36 christos Exp $ */
+/*
+ * tc.sig.c: Signal routine emulations
+ */
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "sh.h"
+
+RCSID("$Id: tc.sig.c,v 3.24 1998/04/08 17:57:36 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 sigret_t
+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);
+# ifndef SIGVOID
+ return(0);
+# endif /* SIGVOID */
+}
+
+/* process all awaiting child signals
+ */
+static sigret_t
+sig_ch_rel()
+{
+ while (stk_ptr > -1)
+ pchild(SIGCHLD);
+# ifdef JOBDEBUG
+ xprintf("signal(SIGCHLD, pchild);\n");
+# endif /* JOBDEBUG */
+ (void) signal(SIGCHLD, pchild);
+# ifndef SIGVOID
+ return(0);
+# endif /* SIGVOID */
+}
+
+
+/* libc.a contains these functions in SYSVREL >= 3. */
+sigret_t
+(*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 */
+}
+
+/* ignore signal
+ */
+void
+xsigignore(a)
+ int a;
+{
+ (void) signal(a, SIG_IGN);
+}
+
+/* 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;
+{
+ 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);
+ }
+ 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);
+ }
+} /* end ourwait */
+
+# ifdef COHERENT
+# undef signal
+sigret_t
+(*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)
+{
+ 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();
+ }
+}
+# endif /* SXA */
+
+#endif /* !BSDSIGS */
+
+#ifdef NEEDsignal
+/* turn into bsd signals */
+sigret_t
+(*xsignal(s, a)) ()
+ int s;
+ signalfun_t a;
+{
+ 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);
+}
+
+#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;
+{
+ sigset_t set, oset;
+ int m;
+ register 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))
+ SETBIT(m, i);
+
+ return (m);
+}
+#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;
+{
+ sigset_t set, oset;
+ int m;
+ register 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))
+ SETBIT(m, i);
+
+ return (m);
+}
+#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;
+{
+ sigset_t set;
+ register int i;
+
+ (void) sigemptyset(&set);
+
+ for (i = 1; i <= MAXSIG; i++)
+ if (ISSET(mask, i))
+ (void) sigaddset(&set, i);
+ (void) sigsuspend(&set);
+}
+
+/*
+ * bsd_signal(sig, func)
+ *
+ * Emulate bsd style signal()
+ */
+sigret_t (*bsd_signal(sig, func)) ()
+ int sig;
+ signalfun_t func;
+{
+ 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);
+ }
+
+ (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);
+}
+#endif /* POSIXSIG */
+
+
+#ifdef SIGSYNCH
+static long Synch_Cnt = 0;
+
+sigret_t
+synch_handler(sno)
+int sno;
+{
+ if (sno != SIGSYNCH)
+ abort();
+ Synch_Cnt++;
+}
+#endif /* SIGSYNCH */
OpenPOWER on IntegriCloud