Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <ctype.h>
5
#include <mach.h>
6
#define Extern extern
7
#include "acid.h"
8
#include "y.tab.h"
9
 
10
static void install(int);
11
 
12
void
13
nocore(void)
14
{
15
	int i;
16
 
17
	if(cormap == 0)
18
		return;
19
 
20
	for (i = 0; i < cormap->nsegs; i++)
21
		if (cormap->seg[i].inuse && cormap->seg[i].fd >= 0)
22
			close(cormap->seg[i].fd);
23
	free(cormap);
24
	cormap = 0;
25
}
26
 
27
void
28
sproc(int pid)
29
{
30
	Lsym *s;
31
	char buf[64];
32
	int i, fcor;
33
 
34
	if(symmap == 0)
35
		error("no map");
36
 
37
	snprint(buf, sizeof(buf), "/proc/%d/mem", pid);
38
	fcor = open(buf, ORDWR);
39
	if(fcor < 0)
40
		error("setproc: open %s: %r", buf);
41
 
42
	checkqid(symmap->seg[0].fd, pid);
43
 
44
	s = look("pid");
45
	s->v->ival = pid;
46
 
47
	nocore();
48
	cormap = attachproc(pid, kernel, fcor, &fhdr);
49
	if (cormap == 0)
50
		error("setproc: can't make coremap: %r");
51
	i = findseg(cormap, "text");
52
	if (i > 0)
53
		cormap->seg[i].name = "*text";
54
	i = findseg(cormap, "data");
55
	if (i > 0)
56
		cormap->seg[i].name = "*data";
57
	install(pid);
58
}
59
 
60
int
61
nproc(char **argv)
62
{
63
	char buf[128];
64
	int pid, i, fd;
65
 
66
	pid = fork();
67
	switch(pid) {
68
	case -1:
69
		error("new: fork %r");
70
	case 0:
71
		rfork(RFNAMEG|RFNOTEG);
72
 
73
		snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());
74
		fd = open(buf, ORDWR);
75
		if(fd < 0)
76
			fatal("new: open %s: %r", buf);
77
		write(fd, "hang", 4);
78
		close(fd);
79
 
80
		close(0);
81
		close(1);
82
		close(2);
83
		for(i = 3; i < NFD; i++)
84
			close(i);
85
 
86
		open("/dev/cons", OREAD);
87
		open("/dev/cons", OWRITE);
88
		open("/dev/cons", OWRITE);
89
		exec(argv[0], argv);
90
		fatal("new: exec %s: %r");
91
	default:
92
		install(pid);
93
		msg(pid, "waitstop");
94
		notes(pid);
95
		sproc(pid);
96
		dostop(pid);
97
		break;
98
	}
99
 
100
	return pid;
101
}
102
 
103
void
104
notes(int pid)
105
{
106
	Lsym *s;
107
	Value *v;
108
	int i, fd;
109
	char buf[128];
110
	List *l, **tail;
111
 
112
	s = look("notes");
113
	if(s == 0)
114
		return;
115
	v = s->v;
116
 
117
	snprint(buf, sizeof(buf), "/proc/%d/note", pid);
118
	fd = open(buf, OREAD);
119
	if(fd < 0)
120
		error("pid=%d: open note: %r", pid);
121
 
122
	v->set = 1;
123
	v->type = TLIST;
124
	v->l = 0;
125
	tail = &v->l;
126
	for(;;) {
127
		i = read(fd, buf, sizeof(buf));
128
		if(i <= 0)
129
			break;
130
		buf[i] = '\0';
131
		l = al(TSTRING);
132
		l->string = strnode(buf);
133
		l->fmt = 's';
134
		*tail = l;
135
		tail = &l->next;
136
	}
137
	close(fd);
138
}
139
 
140
void
141
dostop(int pid)
142
{
143
	Lsym *s;
144
	Node *np, *p;
145
 
146
	s = look("stopped");
147
	if(s && s->proc) {
148
		np = an(ONAME, ZN, ZN);
149
		np->sym = s;
150
		np->fmt = 'D';
151
		np->type = TINT;
152
		p = con(pid);
153
		p->fmt = 'D';
154
		np = an(OCALL, np, p);
155
		execute(np);
156
	}
157
}
158
 
159
static void
160
install(int pid)
161
{
162
	Lsym *s;
163
	List *l;
164
	char buf[128];
165
	int i, fd, new, p;
166
 
167
	new = -1;
168
	for(i = 0; i < Maxproc; i++) {
169
		p = ptab[i].pid;
170
		if(p == pid)
171
			return;
172
		if(p == 0 && new == -1)
173
			new = i;
174
	}
175
	if(new == -1)
176
		error("no free process slots");
177
 
178
	snprint(buf, sizeof(buf), "/proc/%d/ctl", pid);
179
	fd = open(buf, OWRITE);
180
	if(fd < 0)
181
		error("pid=%d: open ctl: %r", pid);
182
	ptab[new].pid = pid;
183
	ptab[new].ctl = fd;
184
 
185
	s = look("proclist");
186
	l = al(TINT);
187
	l->fmt = 'D';
188
	l->ival = pid;
189
	l->next = s->v->l;
190
	s->v->l = l;
191
	s->v->set = 1;
192
}
193
 
194
void
195
deinstall(int pid)
196
{
197
	int i;
198
	Lsym *s;
199
	List *f, **d;
200
 
201
	for(i = 0; i < Maxproc; i++) {
202
		if(ptab[i].pid == pid) {
203
			close(ptab[i].ctl);
204
			ptab[i].pid = 0;
205
			s = look("proclist");
206
			d = &s->v->l;
207
			for(f = *d; f; f = f->next) {
208
				if(f->ival == pid) {
209
					*d = f->next;
210
					break;
211
				}
212
			}
213
			s = look("pid");
214
			if(s->v->ival == pid)
215
				s->v->ival = 0;
216
			return;
217
		}
218
	}
219
}
220
 
221
void
222
msg(int pid, char *msg)
223
{
224
	int i;
225
	int l;
226
	char err[ERRMAX];
227
 
228
	for(i = 0; i < Maxproc; i++) {
229
		if(ptab[i].pid == pid) {
230
			l = strlen(msg);
231
			if(write(ptab[i].ctl, msg, l) != l) {
232
				errstr(err, sizeof err);
233
				if(strcmp(err, "process exited") == 0)
234
					deinstall(pid);
235
				error("msg: pid=%d %s: %s", pid, msg, err);
236
			}
237
			return;
238
		}
239
	}
240
	error("msg: pid=%d: not found for %s", pid, msg);
241
}
242
 
243
char *
244
getstatus(int pid)
245
{
246
	int fd, n;
247
	char *argv[16], buf[64];
248
	static char status[128];
249
 
250
	snprint(buf, sizeof(buf), "/proc/%d/status", pid);
251
	fd = open(buf, OREAD);
252
	if(fd < 0)
253
		error("open %s: %r", buf);
254
 
255
	n = read(fd, status, sizeof(status)-1);
256
	close(fd);
257
	if(n <= 0)
258
		error("read %s: %r", buf);
259
	status[n] = '\0';
260
 
261
	if(tokenize(status, argv, nelem(argv)-1) < 3)
262
		error("tokenize %s: %r", buf);
263
 
264
	return argv[2];
265
}
266
 
267
Waitmsg*
268
waitfor(int pid)
269
{
270
	Waitmsg *w;
271
 
272
	for(;;) {
273
		if((w = wait()) == nil)
274
			error("wait %r");
275
		if(w->pid == pid)
276
			return w;
277
		free(w);
278
	}
279
}