diff options
author | obrien <obrien@FreeBSD.org> | 2000-04-15 04:41:27 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-04-15 04:41:27 +0000 |
commit | 4ad28cefef28ce6bdb44a0532cfe20a2076bc694 (patch) | |
tree | 7679c440a91912ee9586cee3ebab24596c0fe1c4 /contrib/tcsh/tc.sig.c | |
download | FreeBSD-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.c | 418 |
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 */ |