source: trunk/third/tcsh/tc.sig.c @ 9006

Revision 9006, 8.7 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9005, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/tc.sig.c,v 1.1.1.1 1996-10-02 06:09:29 ghudson Exp $ */
2/*
3 * tc.sig.c: Signal routine emulations
4 */
5/*-
6 * Copyright (c) 1980, 1991 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
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. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *      This product includes software developed by the University of
20 *      California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37#include "sh.h"
38
39RCSID("$Id: tc.sig.c,v 1.1.1.1 1996-10-02 06:09:29 ghudson Exp $")
40
41#include "tc.wait.h"
42
43#ifndef BSDSIGS
44
45/* this stack is used to queue signals
46 * we can handle up to MAX_CHLD outstanding children now;
47 */
48#define MAX_CHLD 50
49static struct mysigstack {
50    int     s_w;                /* wait report                   */
51    int     s_errno;            /* errno returned;               */
52    pid_t   s_pid;              /* pid returned                  */
53}       stk[MAX_CHLD];
54static int stk_ptr = -1;
55
56
57# ifdef UNRELSIGS
58/* queue child signals
59 */
60static sigret_t
61sig_ch_queue()
62{
63#  ifdef JOBDEBUG
64    xprintf("queue SIGCHLD\n");
65    flush();
66#  endif /* JOBDEBUG */
67    stk_ptr++;
68    stk[stk_ptr].s_pid = (pid_t) wait(&stk[stk_ptr].s_w);
69    stk[stk_ptr].s_errno = errno;
70    (void) signal(SIGCHLD, sig_ch_queue);
71#  ifndef SIGVOID
72    return(0);
73#  endif /* SIGVOID */
74}
75
76/* process all awaiting child signals
77 */
78static sigret_t
79sig_ch_rel()
80{
81    while (stk_ptr > -1)
82        pchild(SIGCHLD);
83#  ifdef JOBDEBUG
84    xprintf("signal(SIGCHLD, pchild);\n");
85#  endif /* JOBDEBUG */
86    (void) signal(SIGCHLD, pchild);
87#  ifndef SIGVOID
88    return(0);
89#  endif /* SIGVOID */
90}
91
92
93/* libc.a contains these functions in SYSVREL >= 3. */
94sigret_t
95(*xsigset(a, b)) ()
96    int     a;
97    sigret_t  (*b) __P((int));
98{
99    return (signal(a, b));
100}
101
102/* release signal
103 *      release all queued signals and
104 *      set the default signal handler
105 */
106void
107sigrelse(what)
108    int     what;
109{
110    if (what == SIGCHLD)
111        sig_ch_rel();
112
113#  ifdef COHERENT
114    (void) signal(what, what == SIGINT ? pintr : SIG_DFL);
115#  endif /* COHERENT */
116}
117
118/* hold signal
119 * only works with child and interrupt
120 */
121void
122xsighold(what)
123    int     what;
124{
125    if (what == SIGCHLD)
126        (void) signal(SIGCHLD, sig_ch_queue);
127
128#  ifdef COHERENT
129    (void) signal(what, SIG_IGN);
130#  endif /* COHERENT */
131}
132
133/* ignore signal
134 */
135void
136xsigignore(a)
137    int     a;
138{
139    (void) signal(a, SIG_IGN);
140}
141
142/* atomically release one signal
143 */
144void
145xsigpause(what)
146    int     what;
147{
148    /* From: Jim Mattson <mattson%cs@ucsd.edu> */
149    if (what == SIGCHLD)
150        pchild(SIGCHLD);
151}
152
153
154/* return either awaiting processes or do a wait now
155 */
156pid_t
157ourwait(w)
158    int    *w;
159{
160    pid_t pid;
161
162#  ifdef JOBDEBUG
163    xprintf("our wait %d\n", stk_ptr);
164    flush();
165#  endif /* JOBDEBUG */
166
167    if (stk_ptr == -1) {
168        /* stack empty return signal from stack */
169        pid = (pid_t) wait(w);
170#  ifdef JOBDEBUG
171        xprintf("signal(SIGCHLD, pchild);\n");
172#  endif /* JOBDEBUG */
173        (void) signal(SIGCHLD, pchild);
174        return (pid);
175    }
176    else {
177        /* return signal from stack */
178        errno = stk[stk_ptr].s_errno;
179        *w = stk[stk_ptr].s_w;
180        stk_ptr--;
181        return (stk[stk_ptr + 1].s_pid);
182    }
183} /* end ourwait */
184
185#  ifdef COHERENT
186#   undef signal
187sigret_t
188(*xsignal(a, b)) ()
189    int     a;
190    sigret_t  (*b) __P((int));
191{
192    if (a == SIGCHLD)
193        return SIG_DFL;
194    else
195        return (signal(a, b));
196}
197#  endif /* COHERENT */
198
199# endif /* UNRELSIGS */
200
201# ifdef SXA
202/*
203 * SX/A is SYSVREL3 but does not have sys5-sigpause().
204 * I've heard that sigpause() is not defined in SYSVREL3.
205 */
206/* This is not need if you make tcsh by BSD option's cc. */
207void
208sigpause(what)
209{
210    if (what == SIGCHLD) {
211        bsd_sigpause(bsd_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
212    }
213    else if (what == 0) {
214        pause();
215    }
216    else {
217        xprintf("sigpause(%d)\n", what);
218        pause();
219    }
220}
221# endif /* SXA */
222
223#endif /* !BSDSIGS */
224
225#ifdef NEEDsignal
226/* turn into bsd signals */
227sigret_t(*
228         xsignal(s, a)) ()
229    int     s;
230    sigret_t (*a) __P((int));
231{
232    sigvec_t osv, sv;
233
234    (void) mysigvec(s, NULL, &osv);
235    sv = osv;
236    sv.sv_handler = a;
237#ifdef SIG_STK
238    sv.sv_onstack = SIG_STK;
239#endif /* SIG_STK */
240#ifdef SV_BSDSIG
241    sv.sv_flags = SV_BSDSIG;
242#endif /* SV_BSDSIG */
243
244    if (mysigvec(s, &sv, NULL) < 0)
245        return (BADSIG);
246    return (osv.sv_handler);
247}
248
249#endif /* NEEDsignal */
250
251#ifdef POSIXSIGS
252/*
253 * Support for signals.
254 */
255
256extern int errno;
257
258/* Set and test a bit.  Bits numbered 1 to 32 */
259
260#define SETBIT(x, y)    x |= sigmask(y)
261#define ISSET(x, y)     ((x & sigmask(y)) != 0)
262
263#ifdef DEBUG
264# define SHOW_SIGNALS   1       /* to assist in debugging signals */
265#endif /* DEBUG */
266
267#ifdef SHOW_SIGNALS
268char   *show_sig_mask();
269#endif /* SHOW_SIGNALS */
270
271int     debug_signals = 0;
272
273/*
274 * sigsetmask(mask)
275 *
276 * Set a new signal mask.  Return old mask.
277 */
278sigmask_t
279sigsetmask(mask)
280    sigmask_t     mask;
281{
282    sigset_t set, oset;
283    int     m;
284    register int i;
285
286    sigemptyset(&set);
287    sigemptyset(&oset);
288
289    for (i = 1; i <= MAXSIG; i++)
290        if (ISSET(mask, i))
291            sigaddset(&set, i);
292
293    if (sigprocmask(SIG_SETMASK, &set, &oset))
294        xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
295                mask, errno);
296
297    m = 0;
298    for (i = 1; i <= MAXSIG; i++)
299        if (sigismember(&oset, i))
300            SETBIT(m, i);
301
302    return (m);
303}
304
305/*
306 * sigblock(mask)
307 *
308 * Add "mask" set of signals to the present signal mask.
309 * Return old mask.
310 */
311sigmask_t
312sigblock(mask)
313    sigmask_t     mask;
314{
315    sigset_t set, oset;
316    int     m;
317    register int i;
318
319    sigemptyset(&set);
320    sigemptyset(&oset);
321
322    /* Get present set of signals. */
323    if (sigprocmask(SIG_SETMASK, NULL, &set))
324        xprintf("sigblock(0x%x) - sigprocmask failed, errno %d",
325                mask, errno);
326
327    /* Add in signals from mask. */
328    for (i = 1; i <= MAXSIG; i++)
329        if (ISSET(mask, i))
330            sigaddset(&set, i);
331
332    sigprocmask(SIG_SETMASK, &set, &oset);
333
334    /* Return old mask to user. */
335    m = 0;
336    for (i = 1; i <= MAXSIG; i++)
337        if (sigismember(&oset, i))
338            SETBIT(m, i);
339
340    return (m);
341}
342
343
344/*
345 * bsd_sigpause(mask)
346 *
347 * Set new signal mask and wait for signal;
348 * Old mask is restored on signal.
349 */
350void
351bsd_sigpause(mask)
352    sigmask_t     mask;
353{
354    sigset_t set;
355    register int i;
356
357    sigemptyset(&set);
358
359    for (i = 1; i <= MAXSIG; i++)
360        if (ISSET(mask, i))
361            sigaddset(&set, i);
362    sigsuspend(&set);
363}
364
365/*
366 * bsd_signal(sig, func)
367 *
368 * Emulate bsd style signal()
369 */
370sigret_t (*bsd_signal(sig, func))()
371        int sig;
372        sigret_t (*func)();
373{
374        struct sigaction act, oact;
375        sigset_t set;
376        sigret_t (*r_func)();
377
378        if (sig < 0 || sig > MAXSIG) {
379                xprintf("error: bsd_signal(%d) signal out of range\n", sig);
380                return((sigret_t(*)()) SIG_IGN);
381        }
382
383        sigemptyset(&set);
384
385        act.sa_handler = (sigret_t(*)()) func;      /* user function */
386        act.sa_mask = set;                      /* signal mask */
387        act.sa_flags = 0;                       /* no special actions */
388
389        if (sigaction(sig, &act, &oact)) {
390                xprintf("error: bsd_signal(%d) - sigaction failed, errno %d\n",
391                    sig, errno);
392                return((sigret_t(*)()) SIG_IGN);
393        }
394
395        r_func = (sigret_t(*)()) oact.sa_handler;
396        return(r_func);
397}
398#endif /* POSIXSIG */
399
400
401#ifdef SIGSYNCH
402static long Synch_Cnt = 0;
403
404sigret_t
405synch_handler(sno)
406int sno;
407{
408    if (sno != SIGSYNCH)
409        abort();
410    Synch_Cnt++;
411}
412#endif /* SIGSYNCH */
Note: See TracBrowser for help on using the repository browser.