13e12c5d1SDavid du Colombier #include "lib.h" 23e12c5d1SDavid du Colombier #include "sys9.h" 33e12c5d1SDavid du Colombier #include <signal.h> 43e12c5d1SDavid du Colombier #include <errno.h> 53e12c5d1SDavid du Colombier #include <string.h> 63e12c5d1SDavid du Colombier 7*219b2ee8SDavid du Colombier extern sigset_t _psigblocked; 8*219b2ee8SDavid du Colombier 93e12c5d1SDavid du Colombier static struct { 103e12c5d1SDavid du Colombier char *msg; /* just check prefix */ 113e12c5d1SDavid du Colombier int num; 123e12c5d1SDavid du Colombier } sigtab[] = { 133e12c5d1SDavid du Colombier {"hangup", SIGHUP}, 143e12c5d1SDavid du Colombier {"interrupt", SIGINT}, 153e12c5d1SDavid du Colombier {"quit", SIGQUIT}, 163e12c5d1SDavid du Colombier {"alarm", SIGALRM}, 173e12c5d1SDavid du Colombier {"sys: trap: illegal instruction", SIGILL}, 183e12c5d1SDavid du Colombier {"sys: trap: reserved instruction", SIGILL}, 193e12c5d1SDavid du Colombier {"sys: trap: reserved", SIGILL}, 20*219b2ee8SDavid du Colombier {"sys: trap: arithmetic overflow", SIGFPE}, 213e12c5d1SDavid du Colombier {"abort", SIGABRT}, 223e12c5d1SDavid du Colombier {"sys: fp:", SIGFPE}, 233e12c5d1SDavid du Colombier {"exit", SIGKILL}, 243e12c5d1SDavid du Colombier {"die", SIGKILL}, 253e12c5d1SDavid du Colombier {"kill", SIGKILL}, 263e12c5d1SDavid du Colombier {"sys: trap: bus error", SIGSEGV}, 273e12c5d1SDavid du Colombier {"sys: trap: address error", SIGSEGV}, 283e12c5d1SDavid du Colombier {"sys: trap: TLB", SIGSEGV}, 293e12c5d1SDavid du Colombier {"sys: write on closed pipe", SIGPIPE}, 303e12c5d1SDavid du Colombier {"alarm", SIGALRM}, 313e12c5d1SDavid du Colombier {"term", SIGTERM}, 323e12c5d1SDavid du Colombier {"usr1", SIGUSR1}, 333e12c5d1SDavid du Colombier {"usr2", SIGUSR2}, 343e12c5d1SDavid du Colombier }; 353e12c5d1SDavid du Colombier #define NSIGTAB ((sizeof sigtab)/(sizeof (sigtab[0]))) 363e12c5d1SDavid du Colombier 37*219b2ee8SDavid du Colombier void (*_sighdlr[MAXSIG+1])(int, char*, Ureg*); /* 0 initialized: SIG_DFL */ 383e12c5d1SDavid du Colombier 393e12c5d1SDavid du Colombier void 40*219b2ee8SDavid du Colombier (*signal(int sig, void (*func)(int, char*, Ureg*)))(int, char*, Ureg*) 413e12c5d1SDavid du Colombier { 42*219b2ee8SDavid du Colombier void(*oldf)(int, char*, Ureg*); 433e12c5d1SDavid du Colombier 443e12c5d1SDavid du Colombier if(sig <= 0 || sig > MAXSIG){ 453e12c5d1SDavid du Colombier errno = EINVAL; 463e12c5d1SDavid du Colombier return SIG_ERR; 473e12c5d1SDavid du Colombier } 483e12c5d1SDavid du Colombier oldf = _sighdlr[sig]; 493e12c5d1SDavid du Colombier if(sig == SIGKILL) 503e12c5d1SDavid du Colombier return oldf; /* can't catch or ignore SIGKILL */ 513e12c5d1SDavid du Colombier _sighdlr[sig] = func; 523e12c5d1SDavid du Colombier return oldf; 533e12c5d1SDavid du Colombier } 543e12c5d1SDavid du Colombier 55*219b2ee8SDavid du Colombier /* 56*219b2ee8SDavid du Colombier * BUG: improper handling of process signal mask 57*219b2ee8SDavid du Colombier */ 583e12c5d1SDavid du Colombier int 59*219b2ee8SDavid du Colombier sigaction(int sig, struct sigaction *act, struct sigaction *oact) 60*219b2ee8SDavid du Colombier { 61*219b2ee8SDavid du Colombier if(sig <= 0 || sig > MAXSIG || sig == SIGKILL){ 62*219b2ee8SDavid du Colombier errno = EINVAL; 63*219b2ee8SDavid du Colombier return -1; 64*219b2ee8SDavid du Colombier } 65*219b2ee8SDavid du Colombier if(oact){ 66*219b2ee8SDavid du Colombier oact->sa_handler = _sighdlr[sig]; 67*219b2ee8SDavid du Colombier oact->sa_mask = _psigblocked; 68*219b2ee8SDavid du Colombier oact->sa_flags = 0; 69*219b2ee8SDavid du Colombier } 70*219b2ee8SDavid du Colombier if(act){ 71*219b2ee8SDavid du Colombier _sighdlr[sig] = act->sa_handler; 72*219b2ee8SDavid du Colombier } 73*219b2ee8SDavid du Colombier return 0; 74*219b2ee8SDavid du Colombier } 75*219b2ee8SDavid du Colombier 76*219b2ee8SDavid du Colombier /* this is registered in _envsetup */ 77*219b2ee8SDavid du Colombier int 78*219b2ee8SDavid du Colombier _notehandler(Ureg *u, char *msg) 793e12c5d1SDavid du Colombier { 803e12c5d1SDavid du Colombier int i; 81*219b2ee8SDavid du Colombier void(*f)(int, char*, Ureg*); 82*219b2ee8SDavid du Colombier extern void _doatexits(void); /* in stdio/exit.c */ 833e12c5d1SDavid du Colombier 843e12c5d1SDavid du Colombier if(_finishing) 853e12c5d1SDavid du Colombier _finish(0, 0); 863e12c5d1SDavid du Colombier for(i = 0; i<NSIGTAB; i++){ 873e12c5d1SDavid du Colombier if(strncmp(msg, sigtab[i].msg, strlen(sigtab[i].msg)) == 0){ 883e12c5d1SDavid du Colombier f = _sighdlr[sigtab[i].num]; 893e12c5d1SDavid du Colombier if(f == SIG_DFL || f == SIG_ERR) 903e12c5d1SDavid du Colombier break; 91*219b2ee8SDavid du Colombier if(f != SIG_IGN) { 92*219b2ee8SDavid du Colombier _notetramp(sigtab[i].num, f, u); 93*219b2ee8SDavid du Colombier /* notetramp is machine-dependent; doesn't return to here */ 94*219b2ee8SDavid du Colombier } 953e12c5d1SDavid du Colombier _NOTED(0); /* NCONT */ 963e12c5d1SDavid du Colombier return; 973e12c5d1SDavid du Colombier } 983e12c5d1SDavid du Colombier } 99*219b2ee8SDavid du Colombier _doatexits(); 1003e12c5d1SDavid du Colombier _NOTED(1); /* NDFLT */ 1013e12c5d1SDavid du Colombier } 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier int 1043e12c5d1SDavid du Colombier _stringsig(char *nam) 1053e12c5d1SDavid du Colombier { 1063e12c5d1SDavid du Colombier int i; 1073e12c5d1SDavid du Colombier 1083e12c5d1SDavid du Colombier for(i = 0; i<NSIGTAB; i++) 1093e12c5d1SDavid du Colombier if(strncmp(nam, sigtab[i].msg, strlen(sigtab[i].msg)) == 0) 1103e12c5d1SDavid du Colombier return sigtab[i].num; 1113e12c5d1SDavid du Colombier return 0; 1123e12c5d1SDavid du Colombier } 1133e12c5d1SDavid du Colombier 1143e12c5d1SDavid du Colombier char * 1153e12c5d1SDavid du Colombier _sigstring(int sig) 1163e12c5d1SDavid du Colombier { 1173e12c5d1SDavid du Colombier int i; 1183e12c5d1SDavid du Colombier 1193e12c5d1SDavid du Colombier for(i=0; i<NSIGTAB; i++) 1203e12c5d1SDavid du Colombier if(sigtab[i].num == sig) 1213e12c5d1SDavid du Colombier return sigtab[i].msg; 1223e12c5d1SDavid du Colombier return "unknown signal"; 1233e12c5d1SDavid du Colombier } 124