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 */