1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2: 3: /* 4: $Header: b3sig.c,v 1.4 85/08/27 10:56:21 timo Exp $ 5: */ 6: 7: /*Handle interrupts and signals*/ 8: 9: #include "b.h" 10: #include "b0fea.h" 11: #include "b1obj.h" 12: #include "b0con.h" 13: #include "b3scr.h" 14: #include "b3err.h" 15: #include "b3env.h" 16: #ifdef SETJMP 17: #include <setjmp.h> 18: #endif 19: 20: #ifdef SIGNAL 21: #include <signal.h> 22: #endif 23: 24: /*The operating system provides a function signal(s,f) 25: that associates function f with the signal s, and returns 26: a pointer to the previous function associated with s. 27: Then, when signal s occurs, f is called and the function associated with s 28: may or may not be reset. Thus f may need to call signal(s,f) again to. 29: The code here doesn't depend on either interpretation, always being explicit 30: about which handler to use. 31: 32: There are two signals that can come from the user: quit and interrupt. 33: Interrupt should just stop the interpreter and return to B command level; 34: quit should stop the B system completely. 35: All other signals are caused by errors (eg memory exhausted) 36: or come from outside the program, and are therefore fatal. 37: 38: SIG_IGN is the system supplied routine to ignore a signal. 39: SIG_DFL is the system supplied default for a signal. 40: kill(getpid(), signal) kills the program according to 'signal' 41: 42: On BSD systems, SIGTSTP and other signals causing the process to be 43: suspended, and SIGCONT and others that are ignored by default, 44: must not be caught. It is assumed that all these are defined 45: when SIGTSTP is defined. 46: */ 47: 48: #ifdef SIGTSTP 49: Hidden bool must_handle(sig) int sig; { 50: /* Shouldn't we enumerate the list of signals we *do* want to catch? */ 51: /* It seems that new signals are all of the type that should be 52: ignored by most processes... */ 53: switch (sig) { 54: case SIGURG: 55: case SIGSTOP: 56: case SIGTSTP: 57: case SIGCONT: 58: case SIGCHLD: 59: case SIGTTIN: 60: case SIGTTOU: 61: case SIGIO: 62: return No; 63: default: 64: return Yes; 65: } 66: } 67: #else 68: #ifdef SIGCLD /* System V */ 69: #define must_handle(sig) ((sig) != SIGCLD) 70: #else 71: #define must_handle(sig) Yes 72: #endif 73: #endif 74: 75: #ifdef NOT_USED 76: Visible Procedure dump() { 77: if (cntxt != In_prmnv) putprmnv(); 78: #ifdef KILL 79: signal(SIGQUIT, SIG_DFL); 80: kill(getpid(), SIGQUIT); 81: #else 82: exit(-1); 83: #endif 84: } 85: #endif NOT_USED 86: 87: #ifdef SIGNAL 88: Hidden Procedure oops(sig, m) int sig; string m; { 89: signal(sig, SIG_DFL); /* Don't call handler recursive -- just die... */ 90: #ifdef sigmask /* 4.2 BSD */ 91: sigsetmask(0); /* Don't block signals in handler -- just die... */ 92: #endif 93: #ifdef EXT_COMMAND 94: e_done(); 95: #endif 96: fflush(stdout); 97: fprintf(stdout, "*** Oops, %s\n", m); 98: fflush(stdout); 99: if (cntxt != In_prmnv) putprmnv(); 100: #ifdef KILL 101: kill(getpid(), sig); 102: #else 103: exit(-1); 104: #endif 105: } 106: 107: Hidden Procedure burp(sig) int sig; { 108: oops(sig, 109: "I feel suddenly (BURP!) indisposed. I'll call it a day. Sorry."); 110: } 111: 112: Hidden Procedure aog(sig) int sig; { 113: oops(sig, 114: "an act of God has occurred compelling me to discontinue service."); 115: } 116: 117: Hidden Procedure fpe_signal(sig) int sig; { 118: signal(sig /* == SIGFPE*/, fpe_signal); 119: syserr(MESS(3900, "unexpected arithmetic overflow")); 120: } 121: 122: #ifdef SETJMP 123: extern bool awaiting_input; 124: extern jmp_buf read_interrupt; 125: #endif 126: 127: Hidden Procedure intsig(sig) int sig; { /*sig==SIGINT*/ 128: signal(sig, SIG_IGN); 129: int_signal(); 130: signal(sig, intsig); 131: #ifdef SETJMP 132: if (awaiting_input) longjmp(read_interrupt, 1); 133: #endif 134: } 135: 136: #ifdef INTEGRATION 137: 138: Visible Procedure bint_interrupt() { 139: signal(SIGINT, intsig); 140: if (interrupted) intsig(SIGINT); 141: } 142: 143: #endif 144: 145: Hidden int(* setsig(sig, func))() int sig, (*func)(); { 146: /*Set a signal, unless it's being ignored*/ 147: int (*f)()= signal(sig, SIG_IGN); 148: if (f != SIG_IGN) signal(sig, func); 149: return f; 150: } 151: #endif 152: 153: Visible Procedure initsig() { 154: #ifdef SIGNAL 155: int i; 156: for (i = 1; i<=NSIG; ++i) 157: if (must_handle(i)) VOID setsig(i, burp); 158: #ifndef INTEGRATION 159: if (filtered) { 160: VOID setsig(SIGINT, SIG_IGN); 161: VOID setsig(SIGTRAP, intsig); 162: } else { 163: VOID setsig(SIGINT, intsig); 164: VOID setsig(SIGTRAP, burp); 165: } 166: #else 167: VOID setsig(SIGINT, intsig); 168: #endif 169: VOID setsig(SIGQUIT, aog); 170: VOID setsig(SIGTERM, aog); 171: VOID setsig(SIGFPE, fpe_signal); 172: VOID setsig(SIGPIPE, bye); 173: #endif SIGNAL 174: }