1 #include "lib.h" 2 #include "sys9.h" 3 #include <signal.h> 4 #include <errno.h> 5 #include <string.h> 6 7 extern sigset_t _psigblocked; 8 9 static struct { 10 char *msg; /* just check prefix */ 11 int num; 12 } sigtab[] = { 13 {"hangup", SIGHUP}, 14 {"interrupt", SIGINT}, 15 {"quit", SIGQUIT}, 16 {"alarm", SIGALRM}, 17 {"sys: trap: illegal instruction", SIGILL}, 18 {"sys: trap: reserved instruction", SIGILL}, 19 {"sys: trap: reserved", SIGILL}, 20 {"sys: trap: arithmetic overflow", SIGFPE}, 21 {"abort", SIGABRT}, 22 {"sys: fp:", SIGFPE}, 23 {"exit", SIGKILL}, 24 {"die", SIGKILL}, 25 {"kill", SIGKILL}, 26 {"sys: trap: bus error", SIGSEGV}, 27 {"sys: trap: address error", SIGSEGV}, 28 {"sys: trap: TLB", SIGSEGV}, 29 {"sys: write on closed pipe", SIGPIPE}, 30 {"alarm", SIGALRM}, 31 {"term", SIGTERM}, 32 {"usr1", SIGUSR1}, 33 {"usr2", SIGUSR2}, 34 }; 35 #define NSIGTAB ((sizeof sigtab)/(sizeof (sigtab[0]))) 36 37 void (*_sighdlr[MAXSIG+1])(int, char*, Ureg*); /* 0 initialized: SIG_DFL */ 38 39 void 40 (*signal(int sig, void (*func)(int, char*, Ureg*)))(int, char*, Ureg*) 41 { 42 void(*oldf)(int, char*, Ureg*); 43 44 if(sig <= 0 || sig > MAXSIG){ 45 errno = EINVAL; 46 return SIG_ERR; 47 } 48 oldf = _sighdlr[sig]; 49 if(sig == SIGKILL) 50 return oldf; /* can't catch or ignore SIGKILL */ 51 _sighdlr[sig] = func; 52 return oldf; 53 } 54 55 /* 56 * BUG: improper handling of process signal mask 57 */ 58 int 59 sigaction(int sig, struct sigaction *act, struct sigaction *oact) 60 { 61 if(sig <= 0 || sig > MAXSIG || sig == SIGKILL){ 62 errno = EINVAL; 63 return -1; 64 } 65 if(oact){ 66 oact->sa_handler = _sighdlr[sig]; 67 oact->sa_mask = _psigblocked; 68 oact->sa_flags = 0; 69 } 70 if(act){ 71 _sighdlr[sig] = act->sa_handler; 72 } 73 return 0; 74 } 75 76 /* this is registered in _envsetup */ 77 int 78 _notehandler(Ureg *u, char *msg) 79 { 80 int i; 81 void(*f)(int, char*, Ureg*); 82 extern void _doatexits(void); /* in stdio/exit.c */ 83 84 if(_finishing) 85 _finish(0, 0); 86 for(i = 0; i<NSIGTAB; i++){ 87 if(strncmp(msg, sigtab[i].msg, strlen(sigtab[i].msg)) == 0){ 88 f = _sighdlr[sigtab[i].num]; 89 if(f == SIG_DFL || f == SIG_ERR) 90 break; 91 if(f != SIG_IGN) { 92 _notetramp(sigtab[i].num, f, u); 93 /* notetramp is machine-dependent; doesn't return to here */ 94 } 95 _NOTED(0); /* NCONT */ 96 return; 97 } 98 } 99 _doatexits(); 100 _NOTED(1); /* NDFLT */ 101 } 102 103 int 104 _stringsig(char *nam) 105 { 106 int i; 107 108 for(i = 0; i<NSIGTAB; i++) 109 if(strncmp(nam, sigtab[i].msg, strlen(sigtab[i].msg)) == 0) 110 return sigtab[i].num; 111 return 0; 112 } 113 114 char * 115 _sigstring(int sig) 116 { 117 int i; 118 119 for(i=0; i<NSIGTAB; i++) 120 if(sigtab[i].num == sig) 121 return sigtab[i].msg; 122 return "unknown signal"; 123 } 124