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
	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
}