Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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->ax = ret;
67
	if(ret == 0)
68
		u->ax = 1;
69
	u->pc = j[2+JMPBUFPC];
70
	u->sp = j[2+JMPBUFSP] + 4;
71
	_NOTED(3);	/* NRSTR */
72
}