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