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

Revision 12039, 8.9 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12038, which included commits to RCS files with non-trunk default branches.
RevLine 
[12038]1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/tc.sig.c,v 1.1.1.2 1998-10-03 21:10:15 danw Exp $ */
[9005]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
[12038]39RCSID("$Id: tc.sig.c,v 1.1.1.2 1998-10-03 21:10:15 danw Exp $")
[9005]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
[12038]49
50# ifdef UNRELSIGS
[9005]51static struct mysigstack {
52    int     s_w;                /* wait report                   */
53    int     s_errno;            /* errno returned;               */
54    pid_t   s_pid;              /* pid returned                  */
55}       stk[MAX_CHLD];
56static int stk_ptr = -1;
57
58
59/* queue child signals
60 */
61static sigret_t
62sig_ch_queue()
63{
64#  ifdef JOBDEBUG
65    xprintf("queue SIGCHLD\n");
66    flush();
67#  endif /* JOBDEBUG */
68    stk_ptr++;
69    stk[stk_ptr].s_pid = (pid_t) wait(&stk[stk_ptr].s_w);
70    stk[stk_ptr].s_errno = errno;
71    (void) signal(SIGCHLD, sig_ch_queue);
72#  ifndef SIGVOID
73    return(0);
74#  endif /* SIGVOID */
75}
76
77/* process all awaiting child signals
78 */
79static sigret_t
80sig_ch_rel()
81{
82    while (stk_ptr > -1)
83        pchild(SIGCHLD);
84#  ifdef JOBDEBUG
85    xprintf("signal(SIGCHLD, pchild);\n");
86#  endif /* JOBDEBUG */
87    (void) signal(SIGCHLD, pchild);
88#  ifndef SIGVOID
89    return(0);
90#  endif /* SIGVOID */
91}
92
93
94/* libc.a contains these functions in SYSVREL >= 3. */
95sigret_t
96(*xsigset(a, b)) ()
97    int     a;
[12038]98    signalfun_t  b;
[9005]99{
100    return (signal(a, b));
101}
102
103/* release signal
104 *      release all queued signals and
105 *      set the default signal handler
106 */
107void
108sigrelse(what)
109    int     what;
110{
111    if (what == SIGCHLD)
112        sig_ch_rel();
113
114#  ifdef COHERENT
115    (void) signal(what, what == SIGINT ? pintr : SIG_DFL);
116#  endif /* COHERENT */
117}
118
119/* hold signal
120 * only works with child and interrupt
121 */
122void
123xsighold(what)
124    int     what;
125{
126    if (what == SIGCHLD)
127        (void) signal(SIGCHLD, sig_ch_queue);
128
129#  ifdef COHERENT
130    (void) signal(what, SIG_IGN);
131#  endif /* COHERENT */
132}
133
134/* ignore signal
135 */
136void
137xsigignore(a)
138    int     a;
139{
140    (void) signal(a, SIG_IGN);
141}
142
143/* atomically release one signal
144 */
145void
146xsigpause(what)
147    int     what;
148{
149    /* From: Jim Mattson <mattson%cs@ucsd.edu> */
150    if (what == SIGCHLD)
151        pchild(SIGCHLD);
152}
153
154
155/* return either awaiting processes or do a wait now
156 */
157pid_t
158ourwait(w)
159    int    *w;
160{
161    pid_t pid;
162
163#  ifdef JOBDEBUG
[12038]164    xprintf(CGETS(25, 1, "our wait %d\n", stk_ptr));
[9005]165    flush();
166#  endif /* JOBDEBUG */
167
168    if (stk_ptr == -1) {
169        /* stack empty return signal from stack */
170        pid = (pid_t) wait(w);
171#  ifdef JOBDEBUG
172        xprintf("signal(SIGCHLD, pchild);\n");
173#  endif /* JOBDEBUG */
174        (void) signal(SIGCHLD, pchild);
175        return (pid);
176    }
177    else {
178        /* return signal from stack */
179        errno = stk[stk_ptr].s_errno;
180        *w = stk[stk_ptr].s_w;
181        stk_ptr--;
182        return (stk[stk_ptr + 1].s_pid);
183    }
184} /* end ourwait */
185
186#  ifdef COHERENT
187#   undef signal
188sigret_t
189(*xsignal(a, b)) ()
190    int     a;
[12038]191    signalfun_t  b;
[9005]192{
193    if (a == SIGCHLD)
194        return SIG_DFL;
195    else
196        return (signal(a, b));
197}
198#  endif /* COHERENT */
199
200# endif /* UNRELSIGS */
201
202# ifdef SXA
203/*
204 * SX/A is SYSVREL3 but does not have sys5-sigpause().
205 * I've heard that sigpause() is not defined in SYSVREL3.
206 */
207/* This is not need if you make tcsh by BSD option's cc. */
208void
209sigpause(what)
210{
211    if (what == SIGCHLD) {
[12038]212        (void) bsd_sigpause(bsd_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
[9005]213    }
214    else if (what == 0) {
215        pause();
216    }
217    else {
218        xprintf("sigpause(%d)\n", what);
219        pause();
220    }
221}
222# endif /* SXA */
223
224#endif /* !BSDSIGS */
225
226#ifdef NEEDsignal
227/* turn into bsd signals */
[12038]228sigret_t
229(*xsignal(s, a)) ()
[9005]230    int     s;
[12038]231    signalfun_t a;
[9005]232{
233    sigvec_t osv, sv;
234
235    (void) mysigvec(s, NULL, &osv);
236    sv = osv;
237    sv.sv_handler = a;
238#ifdef SIG_STK
239    sv.sv_onstack = SIG_STK;
240#endif /* SIG_STK */
241#ifdef SV_BSDSIG
242    sv.sv_flags = SV_BSDSIG;
243#endif /* SV_BSDSIG */
244
245    if (mysigvec(s, &sv, NULL) < 0)
246        return (BADSIG);
247    return (osv.sv_handler);
248}
249
250#endif /* NEEDsignal */
251
252#ifdef POSIXSIGS
253/*
254 * Support for signals.
255 */
256
257extern int errno;
258
259/* Set and test a bit.  Bits numbered 1 to 32 */
260
261#define SETBIT(x, y)    x |= sigmask(y)
262#define ISSET(x, y)     ((x & sigmask(y)) != 0)
263
264#ifdef DEBUG
265# define SHOW_SIGNALS   1       /* to assist in debugging signals */
266#endif /* DEBUG */
267
268#ifdef SHOW_SIGNALS
269char   *show_sig_mask();
270#endif /* SHOW_SIGNALS */
271
[12038]272#ifndef __PARAGON__
[9005]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
[12038]286    (void) sigemptyset(&set);
287    (void) sigemptyset(&oset);
[9005]288
289    for (i = 1; i <= MAXSIG; i++)
290        if (ISSET(mask, i))
[12038]291            (void) sigaddset(&set, i);
[9005]292
[12038]293    if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1) {
[9005]294        xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
295                mask, errno);
[12038]296    }
[9005]297
298    m = 0;
299    for (i = 1; i <= MAXSIG; i++)
300        if (sigismember(&oset, i))
301            SETBIT(m, i);
302
303    return (m);
304}
[12038]305#endif /* __PARAGON__ */
[9005]306
[12038]307#ifndef __DGUX__
[9005]308/*
309 * sigblock(mask)
310 *
311 * Add "mask" set of signals to the present signal mask.
312 * Return old mask.
313 */
314sigmask_t
315sigblock(mask)
316    sigmask_t     mask;
317{
318    sigset_t set, oset;
319    int     m;
320    register int i;
321
[12038]322    (void) sigemptyset(&set);
323    (void) sigemptyset(&oset);
[9005]324
325    /* Get present set of signals. */
[12038]326    if ((sigprocmask(SIG_SETMASK, NULL, &set)) == -1)
327        stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
[9005]328
329    /* Add in signals from mask. */
330    for (i = 1; i <= MAXSIG; i++)
331        if (ISSET(mask, i))
[12038]332            (void) sigaddset(&set, i);
[9005]333
[12038]334    if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1)
335        stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
[9005]336
337    /* Return old mask to user. */
338    m = 0;
339    for (i = 1; i <= MAXSIG; i++)
340        if (sigismember(&oset, i))
341            SETBIT(m, i);
342
343    return (m);
344}
[12038]345#endif /* __DGUX__ */
[9005]346
347
348/*
349 * bsd_sigpause(mask)
350 *
351 * Set new signal mask and wait for signal;
352 * Old mask is restored on signal.
353 */
354void
355bsd_sigpause(mask)
356    sigmask_t     mask;
357{
358    sigset_t set;
359    register int i;
360
[12038]361    (void) sigemptyset(&set);
[9005]362
363    for (i = 1; i <= MAXSIG; i++)
364        if (ISSET(mask, i))
[12038]365            (void) sigaddset(&set, i);
366    (void) sigsuspend(&set);
[9005]367}
368
369/*
370 * bsd_signal(sig, func)
371 *
372 * Emulate bsd style signal()
373 */
[12038]374sigret_t (*bsd_signal(sig, func)) ()
[9005]375        int sig;
[12038]376        signalfun_t func;
[9005]377{
378        struct sigaction act, oact;
379        sigset_t set;
[12038]380        signalfun_t r_func;
[9005]381
382        if (sig < 0 || sig > MAXSIG) {
[12038]383                xprintf(CGETS(25, 2,
384                        "error: bsd_signal(%d) signal out of range\n"), sig);
385                return((signalfun_t) SIG_IGN);
[9005]386        }
387
[12038]388        (void) sigemptyset(&set);
[9005]389
[12038]390        act.sa_handler = (signalfun_t) func; /* user function */
[9005]391        act.sa_mask = set;                      /* signal mask */
392        act.sa_flags = 0;                       /* no special actions */
393
394        if (sigaction(sig, &act, &oact)) {
[12038]395                xprintf(CGETS(25, 3,
396                        "error: bsd_signal(%d) - sigaction failed, errno %d\n"),
397                        sig, errno);
398                return((signalfun_t) SIG_IGN);
[9005]399        }
400
[12038]401        r_func = (signalfun_t) oact.sa_handler;
[9005]402        return(r_func);
403}
404#endif /* POSIXSIG */
405
406
407#ifdef SIGSYNCH
408static long Synch_Cnt = 0;
409
410sigret_t
411synch_handler(sno)
412int sno;
413{
414    if (sno != SIGSYNCH)
415        abort();
416    Synch_Cnt++;
417}
418#endif /* SIGSYNCH */
Note: See TracBrowser for help on using the repository browser.