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 /* must match signal.h: extern void (*signal(int, void (*)()))(); */ 41 //void (*signal(int sig, void (*func)(int, char*, Ureg*)))(int, char*, Ureg*) 42 void 43 (*signal(int sig, void (*func)()))() 44 { 45 void(*oldf)(int, char*, Ureg*); 46 47 if(sig <= 0 || sig > MAXSIG){ 48 errno = EINVAL; 49 return SIG_ERR; 50 } 51 oldf = _sighdlr[sig]; 52 if(sig == SIGKILL) 53 return oldf; /* can't catch or ignore SIGKILL */ 54 _sighdlr[sig] = func; 55 return oldf; 56 } 57 58 /* BAD CODE - see /sys/src/ape/lib/ap/$objtype/setjmp.s for real code 59 int 60 sigsetjmp(sigjmp_buf buf, int savemask) 61 { 62 int r; 63 64 buf[0] = savemask; 65 buf[1] = _psigblocked; 66 return setjmp(&buf[2]); 67 } 68 */ 69 70 /* 71 * BUG: improper handling of process signal mask 72 */ 73 int 74 sigaction(int sig, struct sigaction *act, struct sigaction *oact) 75 { 76 if(sig <= 0 || sig > MAXSIG || sig == SIGKILL){ 77 errno = EINVAL; 78 return -1; 79 } 80 if(oact){ 81 oact->sa_handler = _sighdlr[sig]; 82 oact->sa_mask = _psigblocked; 83 oact->sa_flags = 0; 84 } 85 if(act){ 86 _sighdlr[sig] = act->sa_handler; 87 } 88 return 0; 89 } 90 91 /* this is registered in _envsetup */ 92 int 93 _notehandler(void *u, char *msg) 94 { 95 int i; 96 void(*f)(int, char*, Ureg*); 97 extern void _doatexits(void); /* in stdio/exit.c */ 98 99 if(_finishing) 100 _finish(0, 0); 101 for(i = 0; i<NSIGTAB; i++){ 102 if(strncmp(msg, sigtab[i].msg, strlen(sigtab[i].msg)) == 0){ 103 f = _sighdlr[sigtab[i].num]; 104 if(f == SIG_DFL || f == SIG_ERR) 105 break; 106 if(f != SIG_IGN) { 107 _notetramp(sigtab[i].num, f, u); 108 /* notetramp is machine-dependent; doesn't return to here */ 109 } 110 _NOTED(0); /* NCONT */ 111 return 0; 112 } 113 } 114 _doatexits(); 115 _NOTED(1); /* NDFLT */ 116 return 0; 117 } 118 119 int 120 _stringsig(char *nam) 121 { 122 int i; 123 124 for(i = 0; i<NSIGTAB; i++) 125 if(strncmp(nam, sigtab[i].msg, strlen(sigtab[i].msg)) == 0) 126 return sigtab[i].num; 127 return 0; 128 } 129 130 char * 131 _sigstring(int sig) 132 { 133 int i; 134 135 for(i=0; i<NSIGTAB; i++) 136 if(sigtab[i].num == sig) 137 return sigtab[i].msg; 138 return "unknown signal"; 139 } 140