1219b2ee8SDavid du Colombier #include "../plan9/lib.h"
2219b2ee8SDavid du Colombier #include "../plan9/sys9.h"
3219b2ee8SDavid du Colombier #include <signal.h>
4*7dd7cddfSDavid du Colombier #include <setjmp.h>
5219b2ee8SDavid du Colombier
6219b2ee8SDavid du Colombier /* A stack to hold pcs when signals nest */
7219b2ee8SDavid du Colombier #define MAXSIGSTACK 20
8219b2ee8SDavid du Colombier typedef struct Pcstack Pcstack;
9219b2ee8SDavid du Colombier static struct Pcstack {
10219b2ee8SDavid du Colombier int sig;
11219b2ee8SDavid du Colombier void (*hdlr)(int, char*, Ureg*);
12219b2ee8SDavid du Colombier unsigned long restorepc;
13*7dd7cddfSDavid du Colombier Ureg *u;
14219b2ee8SDavid du Colombier } pcstack[MAXSIGSTACK];
15219b2ee8SDavid du Colombier static int nstack = 0;
16219b2ee8SDavid du Colombier
17219b2ee8SDavid du Colombier static void notecont(Ureg*, char*);
18219b2ee8SDavid du Colombier
19219b2ee8SDavid du Colombier void
_notetramp(int sig,void (* hdlr)(int,char *,Ureg *),Ureg * u)20219b2ee8SDavid du Colombier _notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u)
21219b2ee8SDavid du Colombier {
22219b2ee8SDavid du Colombier Pcstack *p;
23219b2ee8SDavid du Colombier
24219b2ee8SDavid du Colombier if(nstack >= MAXSIGSTACK)
25219b2ee8SDavid du Colombier _NOTED(1); /* nesting too deep; just do system default */
26219b2ee8SDavid du Colombier p = &pcstack[nstack];
27219b2ee8SDavid du Colombier p->restorepc = u->pc;
28219b2ee8SDavid du Colombier p->sig = sig;
29219b2ee8SDavid du Colombier p->hdlr = hdlr;
30*7dd7cddfSDavid du Colombier p->u = u;
31219b2ee8SDavid du Colombier nstack++;
32219b2ee8SDavid du Colombier u->pc = (unsigned long) notecont;
33219b2ee8SDavid du Colombier _NOTED(2); /* NSAVE: clear note but hold state */
34219b2ee8SDavid du Colombier }
35219b2ee8SDavid du Colombier
36219b2ee8SDavid du Colombier static void
notecont(Ureg * u,char * s)37219b2ee8SDavid du Colombier notecont(Ureg *u, char *s)
38219b2ee8SDavid du Colombier {
39219b2ee8SDavid du Colombier Pcstack *p;
40219b2ee8SDavid du Colombier void(*f)(int, char*, Ureg*);
41219b2ee8SDavid du Colombier
42219b2ee8SDavid du Colombier p = &pcstack[nstack-1];
43219b2ee8SDavid du Colombier f = p->hdlr;
44219b2ee8SDavid du Colombier u->pc = p->restorepc;
45219b2ee8SDavid du Colombier nstack--;
46219b2ee8SDavid du Colombier (*f)(p->sig, s, u);
47219b2ee8SDavid du Colombier _NOTED(3); /* NRSTR */
48219b2ee8SDavid du Colombier }
49*7dd7cddfSDavid du Colombier
50*7dd7cddfSDavid du Colombier #define JMPBUFPC 1
51*7dd7cddfSDavid du Colombier #define JMPBUFSP 0
52*7dd7cddfSDavid du Colombier
53*7dd7cddfSDavid du Colombier extern sigset_t _psigblocked;
54*7dd7cddfSDavid du Colombier
55*7dd7cddfSDavid du Colombier void
siglongjmp(sigjmp_buf j,int ret)56*7dd7cddfSDavid du Colombier siglongjmp(sigjmp_buf j, int ret)
57*7dd7cddfSDavid du Colombier {
58*7dd7cddfSDavid du Colombier struct Ureg *u;
59*7dd7cddfSDavid du Colombier
60*7dd7cddfSDavid du Colombier if(j[0])
61*7dd7cddfSDavid du Colombier _psigblocked = j[1];
62*7dd7cddfSDavid du Colombier if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP])
63*7dd7cddfSDavid du Colombier longjmp(j+2, ret);
64*7dd7cddfSDavid du Colombier u = pcstack[nstack-1].u;
65*7dd7cddfSDavid du Colombier nstack--;
66*7dd7cddfSDavid du Colombier u->ax = ret;
67*7dd7cddfSDavid du Colombier if(ret == 0)
68*7dd7cddfSDavid du Colombier u->ax = 1;
69*7dd7cddfSDavid du Colombier u->pc = j[2+JMPBUFPC];
70*7dd7cddfSDavid du Colombier u->sp = j[2+JMPBUFSP] + 4;
71*7dd7cddfSDavid du Colombier _NOTED(3); /* NRSTR */
72*7dd7cddfSDavid du Colombier }
73