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