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: }

Defined functions

aog defined in line 112; used 2 times
bint_interrupt defined in line 138; never used
burp defined in line 107; used 2 times
dump defined in line 76; used 1 times
fpe_signal defined in line 117; used 2 times
initsig defined in line 153; used 1 times
intsig defined in line 127; used 6 times
must_handle defined in line 49; never used
oops defined in line 88; used 2 times

Defined variables

sig defined in line 145; used 26 times

Defined macros

must_handle defined in line 71; used 1 times
Last modified: 1985-08-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3261
Valid CSS Valid XHTML 1.0 Strict