|
|
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.