|
|
1.1 root 1: /* signal.c
2: Signal handling routines.
3:
4: Copyright (C) 1992 Ian Lance Taylor
5:
6: This file is part of the Taylor UUCP package.
7:
8: This program is free software; you can redistribute it and/or
9: modify it under the terms of the GNU General Public License as
10: published by the Free Software Foundation; either version 2 of the
11: License, or (at your option) any later version.
12:
13: This program is distributed in the hope that it will be useful, but
14: WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16: General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with this program; if not, write to the Free Software
20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22: The author of the program may be contacted at [email protected] or
23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
24: */
25:
26: #include "uucp.h"
27:
28: #include "uudefs.h"
29: #include "sysdep.h"
30: #include "system.h"
31:
32: #include <errno.h>
33:
34: /* Signal handling routines. When we catch a signal, we want to set
35: the appropriate elements of afSignal and afLog_signal to TRUE. If
36: we are on a system which restarts system calls, we may also want to
37: longjmp out. On a system which does not restart system calls,
38: these signal handling routines are well-defined by ANSI C. */
39:
40: #if HAVE_RESTARTABLE_SYSCALLS
41: volatile sig_atomic_t fSjmp;
42: volatile jmp_buf sSjmp_buf;
43: #endif /* HAVE_RESTARTABLE_SYSCALLS */
44:
45: /* Some systems, such as SunOS, have a SA_INTERRUPT bit that must be
46: set in the sigaction structure to force system calls to be
47: interrupted. */
48: #ifndef SA_INTERRUPT
49: #define SA_INTERRUPT 0
50: #endif
51:
52: /* The SVR3 sigset function can be called just like signal, unless
53: system calls are restarted which is extremely unlikely; we prevent
54: this case in sysh.unx. */
55: #if HAVE_SIGSET && ! HAVE_SIGACTION && ! HAVE_SIGVEC
56: #define signal sigset
57: #endif
58:
59: /* The sigvec structure changed from 4.2BSD to 4.3BSD. These macros
60: make the 4.3 code backward compatible. */
61: #ifndef SV_INTERRUPT
62: #define SV_INTERRUPT 0
63: #endif
64: #if ! HAVE_SIGVEC_SV_FLAGS
65: #define sv_flags sv_onstack
66: #endif
67:
68: /* Catch a signal. Reinstall the signal handler if necessary, set the
69: appropriate variables, and do a longjmp if necessary. */
70:
71: RETSIGTYPE
72: ussignal (isig)
73: int isig;
74: {
75: int iindex;
76:
77: #if ! HAVE_SIGACTION && ! HAVE_SIGVEC && ! HAVE_SIGSET
78: (void) signal (isig, ussignal);
79: #endif
80:
81: switch (isig)
82: {
83: default: iindex = INDEXSIG_SIGHUP; break;
84: #ifdef SIGINT
85: case SIGINT: iindex = INDEXSIG_SIGINT; break;
86: #endif
87: #ifdef SIGQUIT
88: case SIGQUIT: iindex = INDEXSIG_SIGQUIT; break;
89: #endif
90: #ifdef SIGTERM
91: case SIGTERM: iindex = INDEXSIG_SIGTERM; break;
92: #endif
93: #ifdef SIGPIPE
94: case SIGPIPE: iindex = INDEXSIG_SIGPIPE; break;
95: #endif
96: }
97:
98: afSignal[iindex] = TRUE;
99: afLog_signal[iindex] = TRUE;
100:
101: #if HAVE_RESTARTABLE_SYSCALLS
102: if (fSjmp)
103: longjmp (sSjmp_buf, 1);
104: #endif /* HAVE_RESTARTABLE_SYSCALLS */
105: }
106:
107: /* Prepare to catch a signal. This is basically the ANSI C routine
108: signal, but it uses sigaction or sigvec instead if they are
109: available. If fforce is FALSE, we do not set the signal if it is
110: currently being ignored. If pfignored is not NULL and fforce is
111: FALSE, then *pfignored will be set to TRUE if the signal was
112: previously being ignored (if fforce is TRUE the value returned in
113: *pfignored is meaningless). If we can't change the signal handler
114: we give a fatal error. */
115:
116: void
117: usset_signal (isig, pfn, fforce, pfignored)
118: int isig;
119: RETSIGTYPE (*pfn) P((int));
120: boolean fforce;
121: boolean *pfignored;
122: {
123: #if HAVE_SIGACTION
124:
125: struct sigaction s;
126:
127: if (! fforce)
128: {
129: (void) (sigemptyset (&s.sa_mask));
130: if (sigaction (isig, (struct sigaction *) NULL, &s) != 0)
131: ulog (LOG_FATAL, "sigaction (%d): %s", isig, strerror (errno));
132:
133: if (s.sa_handler == SIG_IGN)
134: {
135: if (pfignored != NULL)
136: *pfignored = TRUE;
137: return;
138: }
139:
140: if (pfignored != NULL)
141: *pfignored = FALSE;
142: }
143:
144: s.sa_handler = pfn;
145: (void) (sigemptyset (&s.sa_mask));
146: s.sa_flags = SA_INTERRUPT;
147:
148: if (sigaction (isig, &s, (struct sigaction *) NULL) != 0)
149: ulog (LOG_FATAL, "sigaction (%d): %s", isig, strerror (errno));
150:
151: #else /* ! HAVE_SIGACTION */
152: #if HAVE_SIGVEC
153:
154: struct sigvec s;
155:
156: if (! fforce)
157: {
158: if (sigvec (isig, (struct sigvec *) NULL, &s) != 0)
159: ulog (LOG_FATAL, "sigvec (%d): %s", isig, strerror (errno));
160:
161: if (s.sv_handler == SIG_IGN)
162: {
163: if (pfignored != NULL)
164: *pfignored = TRUE;
165: return;
166: }
167:
168: if (pfignored != NULL)
169: *pfignored = FALSE;
170: }
171:
172: s.sv_handler = pfn;
173: s.sv_mask = 0;
174: s.sv_flags = SV_INTERRUPT;
175:
176: if (sigvec (isig, &s, (struct sigvec *) NULL) != 0)
177: ulog (LOG_FATAL, "sigvec (%d): %s", isig, strerror (errno));
178:
179: #else /* ! HAVE_SIGVEC */
180:
181: if (! fforce)
182: {
183: if (signal (isig, SIG_IGN) == SIG_IGN)
184: {
185: if (pfignored != NULL)
186: *pfignored = TRUE;
187: return;
188: }
189:
190: if (pfignored != NULL)
191: *pfignored = FALSE;
192: }
193:
194: (void) signal (isig, pfn);
195:
196: #endif /* ! HAVE_SIGVEC */
197: #endif /* ! HAVE_SIGACTION */
198: }
199:
200: /* The routine called by the system independent code, which always
201: uses the same signal handler. */
202:
203: void
204: usysdep_signal (isig)
205: int isig;
206: {
207: usset_signal (isig, ussignal, FALSE, (boolean *) NULL);
208: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.