1*ce95e1b3SDavid du Colombier #include "../plan9/lib.h"
2*ce95e1b3SDavid du Colombier #include "../plan9/sys9.h"
3*ce95e1b3SDavid du Colombier #include <signal.h>
4*ce95e1b3SDavid du Colombier #include <setjmp.h>
5*ce95e1b3SDavid du Colombier
6*ce95e1b3SDavid du Colombier /* A stack to hold pcs when signals nest */
7*ce95e1b3SDavid du Colombier #define MAXSIGSTACK 20
8*ce95e1b3SDavid du Colombier typedef struct Pcstack Pcstack;
9*ce95e1b3SDavid du Colombier static struct Pcstack {
10*ce95e1b3SDavid du Colombier int sig;
11*ce95e1b3SDavid du Colombier void (*hdlr)(int, char*, Ureg*);
12*ce95e1b3SDavid du Colombier unsigned long long restorepc;
13*ce95e1b3SDavid du Colombier Ureg *u;
14*ce95e1b3SDavid du Colombier } pcstack[MAXSIGSTACK];
15*ce95e1b3SDavid du Colombier static int nstack = 0;
16*ce95e1b3SDavid du Colombier
17*ce95e1b3SDavid du Colombier static void notecont(Ureg*, char*);
18*ce95e1b3SDavid du Colombier
19*ce95e1b3SDavid du Colombier void
_notetramp(int sig,void (* hdlr)(int,char *,Ureg *),Ureg * u)20*ce95e1b3SDavid du Colombier _notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u)
21*ce95e1b3SDavid du Colombier {
22*ce95e1b3SDavid du Colombier Pcstack *p;
23*ce95e1b3SDavid du Colombier
24*ce95e1b3SDavid du Colombier if(nstack >= MAXSIGSTACK)
25*ce95e1b3SDavid du Colombier _NOTED(1); /* nesting too deep; just do system default */
26*ce95e1b3SDavid du Colombier p = &pcstack[nstack];
27*ce95e1b3SDavid du Colombier p->restorepc = u->pc;
28*ce95e1b3SDavid du Colombier p->sig = sig;
29*ce95e1b3SDavid du Colombier p->hdlr = hdlr;
30*ce95e1b3SDavid du Colombier p->u = u;
31*ce95e1b3SDavid du Colombier nstack++;
32*ce95e1b3SDavid du Colombier u->pc = (unsigned long long) notecont;
33*ce95e1b3SDavid du Colombier _NOTED(2); /* NSAVE: clear note but hold state */
34*ce95e1b3SDavid du Colombier }
35*ce95e1b3SDavid du Colombier
36*ce95e1b3SDavid du Colombier static void
notecont(Ureg * u,char * s)37*ce95e1b3SDavid du Colombier notecont(Ureg *u, char *s)
38*ce95e1b3SDavid du Colombier {
39*ce95e1b3SDavid du Colombier Pcstack *p;
40*ce95e1b3SDavid du Colombier void(*f)(int, char*, Ureg*);
41*ce95e1b3SDavid du Colombier
42*ce95e1b3SDavid du Colombier p = &pcstack[nstack-1];
43*ce95e1b3SDavid du Colombier f = p->hdlr;
44*ce95e1b3SDavid du Colombier u->pc = p->restorepc;
45*ce95e1b3SDavid du Colombier nstack--;
46*ce95e1b3SDavid du Colombier (*f)(p->sig, s, u);
47*ce95e1b3SDavid du Colombier _NOTED(3); /* NRSTR */
48*ce95e1b3SDavid du Colombier }
49*ce95e1b3SDavid du Colombier
50*ce95e1b3SDavid du Colombier #define JMPBUFPC 1
51*ce95e1b3SDavid du Colombier #define JMPBUFSP 0
52*ce95e1b3SDavid du Colombier
53*ce95e1b3SDavid du Colombier extern sigset_t _psigblocked;
54*ce95e1b3SDavid du Colombier
55*ce95e1b3SDavid du Colombier void
siglongjmp(sigjmp_buf _j,int ret)56*ce95e1b3SDavid du Colombier siglongjmp(sigjmp_buf _j, int ret)
57*ce95e1b3SDavid du Colombier {
58*ce95e1b3SDavid du Colombier struct Ureg *u;
59*ce95e1b3SDavid du Colombier unsigned long long *j;
60*ce95e1b3SDavid du Colombier
61*ce95e1b3SDavid du Colombier j = (uvlong*)_j;
62*ce95e1b3SDavid du Colombier if(j[0])
63*ce95e1b3SDavid du Colombier _psigblocked = j[1];
64*ce95e1b3SDavid du Colombier if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP])
65*ce95e1b3SDavid du Colombier longjmp((int*)(j+2), ret);
66*ce95e1b3SDavid du Colombier u = pcstack[nstack-1].u;
67*ce95e1b3SDavid du Colombier nstack--;
68*ce95e1b3SDavid du Colombier u->ret = ret;
69*ce95e1b3SDavid du Colombier if(ret == 0)
70*ce95e1b3SDavid du Colombier u->ret = 1;
71*ce95e1b3SDavid du Colombier u->pc = j[2+JMPBUFPC];
72*ce95e1b3SDavid du Colombier u->sp = j[2+JMPBUFSP];
73*ce95e1b3SDavid du Colombier _NOTED(3); /* NRSTR */
74*ce95e1b3SDavid du Colombier }
75