1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2: /* $Header: b2sig.c,v 1.1 84/06/28 00:49:19 timo Exp $ */ 3: 4: /*Handle interrupts and signals*/ 5: #include "b.h" 6: #include "b1obj.h" 7: #include "b0con.h" 8: #include "b2scr.h" 9: #include <signal.h> 10: #include "b2err.h" 11: #include "b2env.h" 12: 13: /*The operating system provides a function signal(s,f) 14: that associates function f with the signal s, and returns 15: a pointer to the previous function associated with s. 16: Then, when signal s occurs, f is called and the function associated with s 17: may or may not be reset. Thus f may need to call signal(s,f) again to. 18: The code here doesn't depend on either interpretation, always being explicit 19: about which handler to use. 20: 21: There are two signals that can come from the user: quit and interrupt. 22: Interrupt should just stop the interpreter and return to B command level; 23: quit should stop the B system completely and produce a dump. 24: All other signals are caused by errors (eg memory exhausted) 25: or come from outside the program, and are therefore fatal. 26: 27: SIG_IGN is the system supplied routine to ignore a signal. 28: SIG_DFL is the system supplied default for a signal. 29: kill(getpid(), signal) kills the program according to 'signal' 30: */ 31: 32: Visible Procedure dump() { 33: signal(SIGQUIT, SIG_DFL); 34: kill(getpid(), SIGQUIT); 35: } 36: 37: Hidden Procedure oops(sig, m) int sig; string m; { 38: fflush(stdout); 39: fprintf(stdout, "*** Oops, %s\n", m); 40: fflush(stdout); 41: if (cntxt != In_prmnv) putprmnv(); 42: signal(sig, SIG_DFL); 43: kill(getpid(), sig); 44: } 45: 46: Hidden Procedure burp(sig) int sig; { 47: oops(sig, 48: "I feel suddenly (BURP!) indisposed. I'll call it a day. Sorry."); 49: } 50: 51: Hidden Procedure aog(sig) int sig; { 52: oops(sig, 53: "an act of God has occurred compelling me to discontinue service."); 54: } 55: 56: Hidden Procedure fpe_signal(sig) int sig; { 57: signal(sig /* == SIGFPE*/, fpe_signal); 58: error("arithmetic overflow"); 59: } 60: 61: Hidden Procedure intsig(sig) int sig; { /*sig==SIGINT*/ 62: signal(sig, SIG_IGN); 63: int_signal(No); 64: } 65: 66: Visible Procedure accept_int() { 67: signal(SIGINT, intsig); 68: } 69: 70: int (*si)(), (*sq)(); 71: bool sawi= No, sawq= No; 72: 73: Hidden Procedure signote(sig) int sig; { 74: /*Note but otherwise ignore a quit or interrupt*/ 75: signal(sig, signote); 76: fprintf(stderr, "*** Just a moment\n"); 77: if (sig == SIGINT) sawi= Yes; 78: else if (sig == SIGQUIT) sawq= Yes; 79: } 80: 81: Hidden int(* setsig(sig, func))() int sig, (*func)(); { 82: /*Set a signal, unless it's being ignored*/ 83: int (*f)()= signal(sig, SIG_IGN); 84: if (f != SIG_IGN) signal(sig, func); 85: return f; 86: } 87: 88: Visible Procedure ignsigs() { 89: /*Henceforth only note quits and interrupts*/ 90: si= setsig(filtered ? SIGTRAP : SIGINT, signote); 91: sq= setsig(SIGQUIT, signote); 92: } 93: 94: Visible Procedure re_sigs() { 95: /*Start processing quits and interrupts again*/ 96: signal(filtered ? SIGTRAP : SIGINT, si); 97: signal(SIGQUIT, sq); 98: if (sawi) { 99: sawi= sawq= No; 100: if (si != SIG_IGN && si != SIG_DFL) (*si)(filtered ? SIGTRAP : SIGINT); 101: } else if (sawq) { 102: sawq= No; 103: if (sq != SIG_IGN && sq != SIG_DFL) (*sq)(SIGQUIT); 104: } 105: } 106: 107: Visible Procedure inisigs() { 108: if (filtered) { 109: VOID setsig(SIGINT, SIG_IGN); 110: VOID setsig(SIGTRAP, intsig); 111: } 112: else { 113: VOID setsig(SIGINT, intsig); 114: VOID setsig(SIGTRAP, burp); 115: } 116: VOID setsig(SIGQUIT, aog); 117: VOID setsig(SIGILL, burp); 118: VOID setsig(SIGIOT, burp); 119: VOID setsig(SIGEMT, burp); 120: VOID setsig(SIGFPE, fpe_signal); 121: VOID setsig(SIGBUS, burp); 122: VOID setsig(SIGSEGV, burp); 123: VOID setsig(SIGSYS, burp); 124: VOID setsig(SIGPIPE, aog); 125: VOID setsig(SIGALRM, burp); 126: VOID setsig(SIGTERM, burp); 127: }