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

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