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 unsigned long restorenpc; 14 Ureg *u; 15 } pcstack[MAXSIGSTACK]; 16 static int nstack = 0; 17 18 static void notecont(Ureg*, char*); 19 20 void 21 _notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u) 22 { 23 Pcstack *p; 24 25 if(nstack >= MAXSIGSTACK) 26 _NOTED(1); /* nesting too deep; just do system default */ 27 p = &pcstack[nstack]; 28 p->restorepc = u->pc; 29 p->restorenpc = u->npc; 30 p->sig = sig; 31 p->hdlr = hdlr; 32 p->u = u; 33 nstack++; 34 u->pc = (unsigned long) notecont; 35 u->npc = u->pc+4; 36 _NOTED(2); /* NSAVE: clear note but hold state */ 37 } 38 39 static void 40 notecont(Ureg *u, char *s) 41 { 42 Pcstack *p; 43 void(*f)(int, char*, Ureg*); 44 45 p = &pcstack[nstack-1]; 46 f = p->hdlr; 47 u->pc = p->restorepc; 48 u->npc = p->restorenpc; 49 nstack--; 50 (*f)(p->sig, s, u); 51 _NOTED(3); /* NRSTR */ 52 } 53 54 int __noterestore(void); 55 56 #define JMPBUFPC 1 57 #define JMPBUFSP 0 58 #define JMPBUFDPC (-8) 59 60 extern sigset_t _psigblocked; 61 62 void 63 siglongjmp(sigjmp_buf j, int ret) 64 { 65 struct Ureg *u; 66 67 if(j[0]) 68 _psigblocked = j[1]; 69 if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP]) 70 longjmp(j+2, ret); 71 u = pcstack[nstack-1].u; 72 nstack--; 73 u->r8 = ret; 74 if(ret == 0) 75 u->r8 = 1; 76 u->r9 = j[JMPBUFPC] - JMPBUFDPC; 77 u->pc = (unsigned long)__noterestore; 78 u->npc = (unsigned long)__noterestore + 4; 79 u->sp = j[JMPBUFSP]; 80 _NOTED(3); /* NRSTR */ 81 } 82