1 /* $Header: /src/pub/tcsh/tc.sig.c,v 3.29 2005/01/18 20:24:51 christos Exp $ */
3 * tc.sig.c: Signal routine emulations
6 * Copyright (c) 1980, 1991 The Regents of the University of California.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 RCSID("$Id: tc.sig.c,v 3.29 2005/01/18 20:24:51 christos Exp $")
41 /* this stack is used to queue signals
42 * we can handle up to MAX_CHLD outstanding children now;
47 static struct mysigstack {
48 int s_w; /* wait report */
49 int s_errno; /* errno returned; */
50 pid_t s_pid; /* pid returned */
52 static int stk_ptr = -1;
55 /* queue child signals
61 xprintf("queue SIGCHLD\n");
63 # endif /* JOBDEBUG */
65 stk[stk_ptr].s_pid = (pid_t) wait(&stk[stk_ptr].s_w);
66 stk[stk_ptr].s_errno = errno;
67 (void) signal(SIGCHLD, sig_ch_queue);
70 /* process all awaiting child signals
78 xprintf("signal(SIGCHLD, pchild);\n");
79 # endif /* JOBDEBUG */
80 (void) signal(SIGCHLD, pchild);
84 /* libc.a contains these functions in SYSVREL >= 3. */
90 return (signal(a, b));
94 * release all queued signals and
95 * set the default signal handler
105 (void) signal(what, what == SIGINT ? pintr : SIG_DFL);
106 # endif /* COHERENT */
110 * only works with child and interrupt
117 (void) signal(SIGCHLD, sig_ch_queue);
120 (void) signal(what, SIG_IGN);
121 # endif /* COHERENT */
130 (void) signal(a, SIG_IGN);
133 /* atomically release one signal
139 /* From: Jim Mattson <mattson%cs@ucsd.edu> */
145 /* return either awaiting processes or do a wait now
154 xprintf(CGETS(25, 1, "our wait %d\n"), stk_ptr);
156 # endif /* JOBDEBUG */
159 /* stack empty return signal from stack */
160 pid = (pid_t) wait(w);
162 xprintf("signal(SIGCHLD, pchild);\n");
163 # endif /* JOBDEBUG */
164 (void) signal(SIGCHLD, pchild);
168 /* return signal from stack */
169 errno = stk[stk_ptr].s_errno;
170 *w = stk[stk_ptr].s_w;
172 return (stk[stk_ptr + 1].s_pid);
186 return (signal(a, b));
188 # endif /* COHERENT */
190 # endif /* UNRELSIGS */
194 * SX/A is SYSVREL3 but does not have sys5-sigpause().
195 * I've heard that sigpause() is not defined in SYSVREL3.
197 /* This is not need if you make tcsh by BSD option's cc. */
201 if (what == SIGCHLD) {
202 (void) bsd_sigpause(bsd_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
204 else if (what == 0) {
208 xprintf("sigpause(%d)\n", what);
214 #endif /* !BSDSIGS */
217 /* turn into bsd signals */
225 (void) mysigvec(s, NULL, &osv);
229 sv.sv_onstack = SIG_STK;
232 sv.sv_flags = SV_BSDSIG;
233 #endif /* SV_BSDSIG */
235 if (mysigvec(s, &sv, NULL) < 0)
237 return (osv.sv_handler);
240 #endif /* NEEDsignal */
244 * Support for signals.
249 /* Set and test a bit. Bits numbered 1 to 32 */
251 #define SETBIT(x, y) x |= sigmask(y)
252 #define ISSET(x, y) ((x & sigmask(y)) != 0)
255 # define SHOW_SIGNALS 1 /* to assist in debugging signals */
259 char *show_sig_mask();
260 #endif /* SHOW_SIGNALS */
266 * Set a new signal mask. Return old mask.
276 (void) sigemptyset(&set);
277 (void) sigemptyset(&oset);
279 for (i = 1; i <= MAXSIG; i++)
281 (void) sigaddset(&set, i);
283 if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1) {
284 xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
289 for (i = 1; i <= MAXSIG; i++)
290 if (sigismember(&oset, i) == 1)
295 #endif /* __PARAGON__ */
301 * Add "mask" set of signals to the present signal mask.
312 (void) sigemptyset(&set);
313 (void) sigemptyset(&oset);
315 /* Get present set of signals. */
316 if ((sigprocmask(SIG_SETMASK, NULL, &set)) == -1)
317 stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
319 /* Add in signals from mask. */
320 for (i = 1; i <= MAXSIG; i++)
322 (void) sigaddset(&set, i);
324 if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1)
325 stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
327 /* Return old mask to user. */
329 for (i = 1; i <= MAXSIG; i++)
330 if (sigismember(&oset, i) == 1)
335 #endif /* __DGUX__ */
341 * Set new signal mask and wait for signal;
342 * Old mask is restored on signal.
351 (void) sigemptyset(&set);
353 for (i = 1; i <= MAXSIG; i++)
355 (void) sigaddset(&set, i);
356 (void) sigsuspend(&set);
360 * bsd_signal(sig, func)
362 * Emulate bsd style signal()
364 RETSIGTYPE (*bsd_signal(sig, func)) ()
368 struct sigaction act, oact;
372 if (sig < 0 || sig > MAXSIG) {
374 "error: bsd_signal(%d) signal out of range\n"), sig);
375 return((signalfun_t) SIG_IGN);
378 (void) sigemptyset(&set);
380 act.sa_handler = (signalfun_t) func; /* user function */
381 act.sa_mask = set; /* signal mask */
382 act.sa_flags = 0; /* no special actions */
384 if (sigaction(sig, &act, &oact)) {
386 "error: bsd_signal(%d) - sigaction failed, errno %d\n"),
388 return((signalfun_t) SIG_IGN);
391 r_func = (signalfun_t) oact.sa_handler;
394 #endif /* POSIXSIG */
398 static long Synch_Cnt = 0;
408 #endif /* SIGSYNCH */