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
signal(int sig,void (* func)())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
sigaction(int sig,struct sigaction * act,struct sigaction * oact)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
_notehandler(void * u,char * msg)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
_stringsig(char * nam)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 *
_sigstring(int sig)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