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 restorepc; 13 Ureg *u; 14 } pcstack[MAXSIGSTACK]; 15 static int nstack = 0; 16 17 static void notecont(Ureg*, char*); 18 19 void 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) notecont; 33 _NOTED(2); /* NSAVE: clear note but hold state */ 34 } 35 36 static void 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 56 siglongjmp(sigjmp_buf j, int ret) 57 { 58 struct Ureg *u; 59 60 if(j[0]) 61 _psigblocked = j[1]; 62 if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP]) 63 longjmp(j+2, ret); 64 u = pcstack[nstack-1].u; 65 nstack--; 66 u->r1 = ret; 67 if(ret == 0) 68 u->r1 = 1; 69 u->pc = j[2+JMPBUFPC]; 70 u->sp = j[2+JMPBUFSP]; 71 _NOTED(3); /* NRSTR */ 72 } 73