xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/signal.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
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