1 /* $Header: /src/pub/tcsh/tc.sig.c,v 3.26 2002/03/08 17:36:47 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.26 2002/03/08 17:36:47 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);
73 /* process all awaiting child signals
81 xprintf("signal(SIGCHLD, pchild);\n");
82 # endif /* JOBDEBUG */
83 (void) signal(SIGCHLD, pchild);
90 /* libc.a contains these functions in SYSVREL >= 3. */
96 return (signal(a, b));
100 * release all queued signals and
101 * set the default signal handler
111 (void) signal(what, what == SIGINT ? pintr : SIG_DFL);
112 # endif /* COHERENT */
116 * only works with child and interrupt
123 (void) signal(SIGCHLD, sig_ch_queue);
126 (void) signal(what, SIG_IGN);
127 # endif /* COHERENT */
136 (void) signal(a, SIG_IGN);
139 /* atomically release one signal
145 /* From: Jim Mattson <mattson%cs@ucsd.edu> */
151 /* return either awaiting processes or do a wait now
160 xprintf(CGETS(25, 1, "our wait %d\n"), stk_ptr);
162 # endif /* JOBDEBUG */
165 /* stack empty return signal from stack */
166 pid = (pid_t) wait(w);
168 xprintf("signal(SIGCHLD, pchild);\n");
169 # endif /* JOBDEBUG */
170 (void) signal(SIGCHLD, pchild);
174 /* return signal from stack */
175 errno = stk[stk_ptr].s_errno;
176 *w = stk[stk_ptr].s_w;
178 return (stk[stk_ptr + 1].s_pid);
192 return (signal(a, b));
194 # endif /* COHERENT */
196 # endif /* UNRELSIGS */
200 * SX/A is SYSVREL3 but does not have sys5-sigpause().
201 * I've heard that sigpause() is not defined in SYSVREL3.
203 /* This is not need if you make tcsh by BSD option's cc. */
207 if (what == SIGCHLD) {
208 (void) bsd_sigpause(bsd_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
210 else if (what == 0) {
214 xprintf("sigpause(%d)\n", what);
220 #endif /* !BSDSIGS */
223 /* turn into bsd signals */
231 (void) mysigvec(s, NULL, &osv);
235 sv.sv_onstack = SIG_STK;
238 sv.sv_flags = SV_BSDSIG;
239 #endif /* SV_BSDSIG */
241 if (mysigvec(s, &sv, NULL) < 0)
243 return (osv.sv_handler);
246 #endif /* NEEDsignal */
250 * Support for signals.
255 /* Set and test a bit. Bits numbered 1 to 32 */
257 #define SETBIT(x, y) x |= sigmask(y)
258 #define ISSET(x, y) ((x & sigmask(y)) != 0)
261 # define SHOW_SIGNALS 1 /* to assist in debugging signals */
265 char *show_sig_mask();
266 #endif /* SHOW_SIGNALS */
272 * Set a new signal mask. Return old mask.
282 (void) sigemptyset(&set);
283 (void) sigemptyset(&oset);
285 for (i = 1; i <= MAXSIG; i++)
287 (void) sigaddset(&set, i);
289 if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1) {
290 xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
295 for (i = 1; i <= MAXSIG; i++)
296 if (sigismember(&oset, i))
301 #endif /* __PARAGON__ */
307 * Add "mask" set of signals to the present signal mask.
318 (void) sigemptyset(&set);
319 (void) sigemptyset(&oset);
321 /* Get present set of signals. */
322 if ((sigprocmask(SIG_SETMASK, NULL, &set)) == -1)
323 stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
325 /* Add in signals from mask. */
326 for (i = 1; i <= MAXSIG; i++)
328 (void) sigaddset(&set, i);
330 if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1)
331 stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
333 /* Return old mask to user. */
335 for (i = 1; i <= MAXSIG; i++)
336 if (sigismember(&oset, i))
341 #endif /* __DGUX__ */
347 * Set new signal mask and wait for signal;
348 * Old mask is restored on signal.
357 (void) sigemptyset(&set);
359 for (i = 1; i <= MAXSIG; i++)
361 (void) sigaddset(&set, i);
362 (void) sigsuspend(&set);
366 * bsd_signal(sig, func)
368 * Emulate bsd style signal()
370 sigret_t (*bsd_signal(sig, func)) ()
374 struct sigaction act, oact;
378 if (sig < 0 || sig > MAXSIG) {
380 "error: bsd_signal(%d) signal out of range\n"), sig);
381 return((signalfun_t) SIG_IGN);
384 (void) sigemptyset(&set);
386 act.sa_handler = (signalfun_t) func; /* user function */
387 act.sa_mask = set; /* signal mask */
388 act.sa_flags = 0; /* no special actions */
390 if (sigaction(sig, &act, &oact)) {
392 "error: bsd_signal(%d) - sigaction failed, errno %d\n"),
394 return((signalfun_t) SIG_IGN);
397 r_func = (signalfun_t) oact.sa_handler;
400 #endif /* POSIXSIG */
404 static long Synch_Cnt = 0;
414 #endif /* SIGSYNCH */