2 Signal handling routines.
4 Copyright (C) 1992 Ian Lance Taylor
6 This file is part of the Taylor UUCP package.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 The author of the program may be contacted at ian@airs.com or
23 c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
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. */
40 #if HAVE_RESTARTABLE_SYSCALLS
41 volatile sig_atomic_t fSjmp;
42 volatile jmp_buf sSjmp_buf;
43 #endif /* HAVE_RESTARTABLE_SYSCALLS */
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
49 #define SA_INTERRUPT 0
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
59 /* The sigvec structure changed from 4.2BSD to 4.3BSD. These macros
60 make the 4.3 code backward compatible. */
62 #define SV_INTERRUPT 0
64 #if ! HAVE_SIGVEC_SV_FLAGS
65 #define sv_flags sv_onstack
68 /* Catch a signal. Reinstall the signal handler if necessary, set the
69 appropriate variables, and do a longjmp if necessary. */
77 #if ! HAVE_SIGACTION && ! HAVE_SIGVEC && ! HAVE_SIGSET
78 (void) signal (isig, ussignal);
83 default: iindex = INDEXSIG_SIGHUP; break;
85 case SIGINT: iindex = INDEXSIG_SIGINT; break;
88 case SIGQUIT: iindex = INDEXSIG_SIGQUIT; break;
91 case SIGTERM: iindex = INDEXSIG_SIGTERM; break;
94 case SIGPIPE: iindex = INDEXSIG_SIGPIPE; break;
98 afSignal[iindex] = TRUE;
99 afLog_signal[iindex] = TRUE;
101 #if HAVE_RESTARTABLE_SYSCALLS
103 longjmp (sSjmp_buf, 1);
104 #endif /* HAVE_RESTARTABLE_SYSCALLS */
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. */
117 usset_signal (isig, pfn, fforce, pfignored)
119 RETSIGTYPE (*pfn) P((int));
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));
133 if (s.sa_handler == SIG_IGN)
135 if (pfignored != NULL)
140 if (pfignored != NULL)
145 (void) (sigemptyset (&s.sa_mask));
146 s.sa_flags = SA_INTERRUPT;
148 if (sigaction (isig, &s, (struct sigaction *) NULL) != 0)
149 ulog (LOG_FATAL, "sigaction (%d): %s", isig, strerror (errno));
151 #else /* ! HAVE_SIGACTION */
158 if (sigvec (isig, (struct sigvec *) NULL, &s) != 0)
159 ulog (LOG_FATAL, "sigvec (%d): %s", isig, strerror (errno));
161 if (s.sv_handler == SIG_IGN)
163 if (pfignored != NULL)
168 if (pfignored != NULL)
174 s.sv_flags = SV_INTERRUPT;
176 if (sigvec (isig, &s, (struct sigvec *) NULL) != 0)
177 ulog (LOG_FATAL, "sigvec (%d): %s", isig, strerror (errno));
179 #else /* ! HAVE_SIGVEC */
183 if (signal (isig, SIG_IGN) == SIG_IGN)
185 if (pfignored != NULL)
190 if (pfignored != NULL)
194 (void) signal (isig, pfn);
196 #endif /* ! HAVE_SIGVEC */
197 #endif /* ! HAVE_SIGACTION */
200 /* The routine called by the system independent code, which always
201 uses the same signal handler. */
204 usysdep_signal (isig)
207 usset_signal (isig, ussignal, FALSE, (boolean *) NULL);