xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/signal.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include "lib.h"
23e12c5d1SDavid du Colombier #include "sys9.h"
33e12c5d1SDavid du Colombier #include <signal.h>
43e12c5d1SDavid du Colombier #include <errno.h>
53e12c5d1SDavid du Colombier #include <string.h>
63e12c5d1SDavid du Colombier 
7*219b2ee8SDavid du Colombier extern sigset_t	_psigblocked;
8*219b2ee8SDavid du Colombier 
93e12c5d1SDavid du Colombier static struct {
103e12c5d1SDavid du Colombier 	char	*msg;	/* just check prefix */
113e12c5d1SDavid du Colombier 	int	num;
123e12c5d1SDavid du Colombier } sigtab[] = {
133e12c5d1SDavid du Colombier 	{"hangup",				SIGHUP},
143e12c5d1SDavid du Colombier 	{"interrupt",				SIGINT},
153e12c5d1SDavid du Colombier 	{"quit",				SIGQUIT},
163e12c5d1SDavid du Colombier 	{"alarm",				SIGALRM},
173e12c5d1SDavid du Colombier 	{"sys: trap: illegal instruction",	SIGILL},
183e12c5d1SDavid du Colombier 	{"sys: trap: reserved instruction",	SIGILL},
193e12c5d1SDavid du Colombier 	{"sys: trap: reserved",			SIGILL},
20*219b2ee8SDavid du Colombier 	{"sys: trap: arithmetic overflow",	SIGFPE},
213e12c5d1SDavid du Colombier 	{"abort",				SIGABRT},
223e12c5d1SDavid du Colombier 	{"sys: fp:",				SIGFPE},
233e12c5d1SDavid du Colombier 	{"exit",				SIGKILL},
243e12c5d1SDavid du Colombier 	{"die",					SIGKILL},
253e12c5d1SDavid du Colombier 	{"kill",				SIGKILL},
263e12c5d1SDavid du Colombier 	{"sys: trap: bus error",		SIGSEGV},
273e12c5d1SDavid du Colombier 	{"sys: trap: address error",		SIGSEGV},
283e12c5d1SDavid du Colombier 	{"sys: trap: TLB",			SIGSEGV},
293e12c5d1SDavid du Colombier 	{"sys: write on closed pipe",		SIGPIPE},
303e12c5d1SDavid du Colombier 	{"alarm",				SIGALRM},
313e12c5d1SDavid du Colombier 	{"term",				SIGTERM},
323e12c5d1SDavid du Colombier 	{"usr1",				SIGUSR1},
333e12c5d1SDavid du Colombier 	{"usr2",				SIGUSR2},
343e12c5d1SDavid du Colombier };
353e12c5d1SDavid du Colombier #define NSIGTAB ((sizeof sigtab)/(sizeof (sigtab[0])))
363e12c5d1SDavid du Colombier 
37*219b2ee8SDavid du Colombier void	(*_sighdlr[MAXSIG+1])(int, char*, Ureg*); /* 0 initialized: SIG_DFL */
383e12c5d1SDavid du Colombier 
393e12c5d1SDavid du Colombier void
40*219b2ee8SDavid du Colombier (*signal(int sig, void (*func)(int, char*, Ureg*)))(int, char*, Ureg*)
413e12c5d1SDavid du Colombier {
42*219b2ee8SDavid du Colombier 	void(*oldf)(int, char*, Ureg*);
433e12c5d1SDavid du Colombier 
443e12c5d1SDavid du Colombier 	if(sig <= 0 || sig > MAXSIG){
453e12c5d1SDavid du Colombier 		errno = EINVAL;
463e12c5d1SDavid du Colombier 		return SIG_ERR;
473e12c5d1SDavid du Colombier 	}
483e12c5d1SDavid du Colombier 	oldf = _sighdlr[sig];
493e12c5d1SDavid du Colombier 	if(sig == SIGKILL)
503e12c5d1SDavid du Colombier 		return oldf;	/* can't catch or ignore SIGKILL */
513e12c5d1SDavid du Colombier 	_sighdlr[sig] = func;
523e12c5d1SDavid du Colombier 	return oldf;
533e12c5d1SDavid du Colombier }
543e12c5d1SDavid du Colombier 
55*219b2ee8SDavid du Colombier /*
56*219b2ee8SDavid du Colombier  * BUG: improper handling of process signal mask
57*219b2ee8SDavid du Colombier  */
583e12c5d1SDavid du Colombier int
59*219b2ee8SDavid du Colombier sigaction(int sig, struct sigaction *act, struct sigaction *oact)
60*219b2ee8SDavid du Colombier {
61*219b2ee8SDavid du Colombier 	if(sig <= 0 || sig > MAXSIG || sig == SIGKILL){
62*219b2ee8SDavid du Colombier 		errno = EINVAL;
63*219b2ee8SDavid du Colombier 		return -1;
64*219b2ee8SDavid du Colombier 	}
65*219b2ee8SDavid du Colombier 	if(oact){
66*219b2ee8SDavid du Colombier 		oact->sa_handler = _sighdlr[sig];
67*219b2ee8SDavid du Colombier 		oact->sa_mask = _psigblocked;
68*219b2ee8SDavid du Colombier 		oact->sa_flags = 0;
69*219b2ee8SDavid du Colombier 	}
70*219b2ee8SDavid du Colombier 	if(act){
71*219b2ee8SDavid du Colombier 		_sighdlr[sig] = act->sa_handler;
72*219b2ee8SDavid du Colombier 	}
73*219b2ee8SDavid du Colombier 	return 0;
74*219b2ee8SDavid du Colombier }
75*219b2ee8SDavid du Colombier 
76*219b2ee8SDavid du Colombier /* this is registered in _envsetup */
77*219b2ee8SDavid du Colombier int
78*219b2ee8SDavid du Colombier _notehandler(Ureg *u, char *msg)
793e12c5d1SDavid du Colombier {
803e12c5d1SDavid du Colombier 	int i;
81*219b2ee8SDavid du Colombier 	void(*f)(int, char*, Ureg*);
82*219b2ee8SDavid du Colombier 	extern void _doatexits(void);	/* in stdio/exit.c */
833e12c5d1SDavid du Colombier 
843e12c5d1SDavid du Colombier 	if(_finishing)
853e12c5d1SDavid du Colombier 		_finish(0, 0);
863e12c5d1SDavid du Colombier 	for(i = 0; i<NSIGTAB; i++){
873e12c5d1SDavid du Colombier 		if(strncmp(msg, sigtab[i].msg, strlen(sigtab[i].msg)) == 0){
883e12c5d1SDavid du Colombier 			f = _sighdlr[sigtab[i].num];
893e12c5d1SDavid du Colombier 			if(f == SIG_DFL || f == SIG_ERR)
903e12c5d1SDavid du Colombier 				break;
91*219b2ee8SDavid du Colombier 			if(f != SIG_IGN) {
92*219b2ee8SDavid du Colombier 				_notetramp(sigtab[i].num, f, u);
93*219b2ee8SDavid du Colombier 				/* notetramp is machine-dependent; doesn't return to here */
94*219b2ee8SDavid du Colombier 			}
953e12c5d1SDavid du Colombier 			_NOTED(0); /* NCONT */
963e12c5d1SDavid du Colombier 			return;
973e12c5d1SDavid du Colombier 		}
983e12c5d1SDavid du Colombier 	}
99*219b2ee8SDavid du Colombier 	_doatexits();
1003e12c5d1SDavid du Colombier 	_NOTED(1); /* NDFLT */
1013e12c5d1SDavid du Colombier }
1023e12c5d1SDavid du Colombier 
1033e12c5d1SDavid du Colombier int
1043e12c5d1SDavid du Colombier _stringsig(char *nam)
1053e12c5d1SDavid du Colombier {
1063e12c5d1SDavid du Colombier 	int i;
1073e12c5d1SDavid du Colombier 
1083e12c5d1SDavid du Colombier 	for(i = 0; i<NSIGTAB; i++)
1093e12c5d1SDavid du Colombier 		if(strncmp(nam, sigtab[i].msg, strlen(sigtab[i].msg)) == 0)
1103e12c5d1SDavid du Colombier 			return sigtab[i].num;
1113e12c5d1SDavid du Colombier 	return 0;
1123e12c5d1SDavid du Colombier }
1133e12c5d1SDavid du Colombier 
1143e12c5d1SDavid du Colombier char *
1153e12c5d1SDavid du Colombier _sigstring(int sig)
1163e12c5d1SDavid du Colombier {
1173e12c5d1SDavid du Colombier 	int i;
1183e12c5d1SDavid du Colombier 
1193e12c5d1SDavid du Colombier 	for(i=0; i<NSIGTAB; i++)
1203e12c5d1SDavid du Colombier 		if(sigtab[i].num == sig)
1213e12c5d1SDavid du Colombier 			return sigtab[i].msg;
1223e12c5d1SDavid du Colombier 	return "unknown signal";
1233e12c5d1SDavid du Colombier }
124