xref: /freebsd/contrib/tcsh/tc.sig.c (revision 688f58d2da3b937bec8a97bc9dc9541bf6ab41b0)
1c80476e4SDavid E. O'Brien /*
2c80476e4SDavid E. O'Brien  * tc.sig.c: Signal routine emulations
3c80476e4SDavid E. O'Brien  */
4c80476e4SDavid E. O'Brien /*-
5c80476e4SDavid E. O'Brien  * Copyright (c) 1980, 1991 The Regents of the University of California.
6c80476e4SDavid E. O'Brien  * All rights reserved.
7c80476e4SDavid E. O'Brien  *
8c80476e4SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
9c80476e4SDavid E. O'Brien  * modification, are permitted provided that the following conditions
10c80476e4SDavid E. O'Brien  * are met:
11c80476e4SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
12c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer.
13c80476e4SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
14c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
15c80476e4SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
1629301572SMark Peek  * 3. Neither the name of the University nor the names of its contributors
17c80476e4SDavid E. O'Brien  *    may be used to endorse or promote products derived from this software
18c80476e4SDavid E. O'Brien  *    without specific prior written permission.
19c80476e4SDavid E. O'Brien  *
20c80476e4SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21c80476e4SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c80476e4SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c80476e4SDavid E. O'Brien  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24c80476e4SDavid E. O'Brien  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c80476e4SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c80476e4SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c80476e4SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c80476e4SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c80476e4SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c80476e4SDavid E. O'Brien  * SUCH DAMAGE.
31c80476e4SDavid E. O'Brien  */
32c80476e4SDavid E. O'Brien #include "sh.h"
33c80476e4SDavid E. O'Brien #include "tc.wait.h"
34c80476e4SDavid E. O'Brien 
35c80476e4SDavid E. O'Brien void
sigset_interrupting(int sig,void (* fn)(int))3645e5710bSMark Peek sigset_interrupting(int sig, void (*fn) (int))
37c80476e4SDavid E. O'Brien {
3845e5710bSMark Peek     struct sigaction act;
39c80476e4SDavid E. O'Brien 
4045e5710bSMark Peek     act.sa_handler = fn;
4145e5710bSMark Peek     sigemptyset(&act.sa_mask);
4245e5710bSMark Peek     act.sa_flags = 0;
4345e5710bSMark Peek     if (sigaction(sig, &act, NULL) == 0) {
44c80476e4SDavid E. O'Brien 	sigset_t set;
4545e5710bSMark Peek 	sigemptyset(&set);
4645e5710bSMark Peek 	sigaddset(&set, sig);
4745e5710bSMark Peek 	sigprocmask(SIG_UNBLOCK, &set, NULL);
4845e5710bSMark Peek     }
49c80476e4SDavid E. O'Brien }
50c80476e4SDavid E. O'Brien 
5145e5710bSMark Peek static volatile sig_atomic_t alrmcatch_pending; /* = 0; */
5245e5710bSMark Peek static volatile sig_atomic_t pchild_pending; /* = 0; */
5345e5710bSMark Peek static volatile sig_atomic_t phup_pending; /* = 0; */
5445e5710bSMark Peek static volatile sig_atomic_t pintr_pending; /* = 0; */
5545e5710bSMark Peek int alrmcatch_disabled; /* = 0; */
5645e5710bSMark Peek int phup_disabled; /* = 0; */
5745e5710bSMark Peek int pchild_disabled; /* = 0; */
5845e5710bSMark Peek int pintr_disabled; /* = 0; */
5945e5710bSMark Peek 
60*9ccc37e3SMark Peek int
handle_pending_signals(void)6145e5710bSMark Peek handle_pending_signals(void)
62c80476e4SDavid E. O'Brien {
63*9ccc37e3SMark Peek     int rv = 0;
6445e5710bSMark Peek     if (!phup_disabled && phup_pending) {
6545e5710bSMark Peek 	phup_pending = 0;
66*9ccc37e3SMark Peek 	handle_interrupt++;
6745e5710bSMark Peek 	phup();
68*9ccc37e3SMark Peek 	handle_interrupt--;
6945e5710bSMark Peek     }
7045e5710bSMark Peek     if (!pintr_disabled && pintr_pending) {
7145e5710bSMark Peek 	pintr_pending = 0;
72*9ccc37e3SMark Peek 	handle_interrupt++;
7345e5710bSMark Peek 	pintr();
74*9ccc37e3SMark Peek 	handle_interrupt--;
75*9ccc37e3SMark Peek 	rv = 1;
7645e5710bSMark Peek     }
7745e5710bSMark Peek     if (!pchild_disabled && pchild_pending) {
7845e5710bSMark Peek 	pchild_pending = 0;
79*9ccc37e3SMark Peek 	handle_interrupt++;
8045e5710bSMark Peek 	pchild();
81*9ccc37e3SMark Peek 	handle_interrupt--;
8245e5710bSMark Peek     }
8345e5710bSMark Peek     if (!alrmcatch_disabled && alrmcatch_pending) {
8445e5710bSMark Peek 	alrmcatch_pending = 0;
85*9ccc37e3SMark Peek 	handle_interrupt++;
8645e5710bSMark Peek 	alrmcatch();
87*9ccc37e3SMark Peek 	handle_interrupt--;
8845e5710bSMark Peek     }
89*9ccc37e3SMark Peek     return rv;
90c80476e4SDavid E. O'Brien }
91c80476e4SDavid E. O'Brien 
9245e5710bSMark Peek void
queue_alrmcatch(int sig)9345e5710bSMark Peek queue_alrmcatch(int sig)
94c80476e4SDavid E. O'Brien {
9545e5710bSMark Peek     USE(sig);
9645e5710bSMark Peek     alrmcatch_pending = 1;
97c80476e4SDavid E. O'Brien }
9845e5710bSMark Peek 
9945e5710bSMark Peek void
queue_pchild(int sig)10045e5710bSMark Peek queue_pchild(int sig)
10145e5710bSMark Peek {
10245e5710bSMark Peek     USE(sig);
10345e5710bSMark Peek     pchild_pending = 1;
10445e5710bSMark Peek }
10545e5710bSMark Peek 
10645e5710bSMark Peek void
queue_phup(int sig)10745e5710bSMark Peek queue_phup(int sig)
10845e5710bSMark Peek {
10945e5710bSMark Peek     USE(sig);
11045e5710bSMark Peek     phup_pending = 1;
11145e5710bSMark Peek }
11245e5710bSMark Peek 
11345e5710bSMark Peek void
queue_pintr(int sig)11445e5710bSMark Peek queue_pintr(int sig)
11545e5710bSMark Peek {
11645e5710bSMark Peek     USE(sig);
11745e5710bSMark Peek     pintr_pending = 1;
11845e5710bSMark Peek }
11945e5710bSMark Peek 
12045e5710bSMark Peek void
disabled_cleanup(void * xdisabled)12145e5710bSMark Peek disabled_cleanup(void *xdisabled)
12245e5710bSMark Peek {
12345e5710bSMark Peek     int *disabled;
12445e5710bSMark Peek 
12545e5710bSMark Peek     disabled = xdisabled;
12645e5710bSMark Peek     if (--*disabled == 0)
12745e5710bSMark Peek 	handle_pending_signals();
12845e5710bSMark Peek }
12945e5710bSMark Peek 
13045e5710bSMark Peek void
pintr_disabled_restore(void * xold)13145e5710bSMark Peek pintr_disabled_restore(void *xold)
13245e5710bSMark Peek {
13345e5710bSMark Peek     int *old;
13445e5710bSMark Peek 
13545e5710bSMark Peek     old = xold;
13645e5710bSMark Peek     pintr_disabled = *old;
13745e5710bSMark Peek }
13845e5710bSMark Peek 
13945e5710bSMark Peek void
pintr_push_enable(int * saved)14045e5710bSMark Peek pintr_push_enable(int *saved)
14145e5710bSMark Peek {
14245e5710bSMark Peek     *saved = pintr_disabled;
14345e5710bSMark Peek     pintr_disabled = 0;
14445e5710bSMark Peek     cleanup_push(saved, pintr_disabled_restore);
14545e5710bSMark Peek     handle_pending_signals();
14645e5710bSMark Peek }
147