xref: /plan9/sys/src/cmd/acid/proc.c (revision 59cc4ca53493a3c6d2349fe2b7f7c40f7dce7294)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <ctype.h>
5bd389b36SDavid du Colombier #include <mach.h>
6bd389b36SDavid du Colombier #define Extern extern
7bd389b36SDavid du Colombier #include "acid.h"
8bd389b36SDavid du Colombier #include "y.tab.h"
9bd389b36SDavid du Colombier 
10219b2ee8SDavid du Colombier static void install(int);
11219b2ee8SDavid du Colombier 
127dd7cddfSDavid du Colombier void
137dd7cddfSDavid du Colombier nocore(void)
14219b2ee8SDavid du Colombier {
157dd7cddfSDavid du Colombier 	int i;
16219b2ee8SDavid du Colombier 
177dd7cddfSDavid du Colombier 	if(cormap == 0)
187dd7cddfSDavid du Colombier 		return;
19219b2ee8SDavid du Colombier 
207dd7cddfSDavid du Colombier 	for (i = 0; i < cormap->nsegs; i++)
217dd7cddfSDavid du Colombier 		if (cormap->seg[i].inuse && cormap->seg[i].fd >= 0)
227dd7cddfSDavid du Colombier 			close(cormap->seg[i].fd);
237dd7cddfSDavid du Colombier 	free(cormap);
247dd7cddfSDavid du Colombier 	cormap = 0;
25219b2ee8SDavid du Colombier }
26219b2ee8SDavid du Colombier 
27bd389b36SDavid du Colombier void
28bd389b36SDavid du Colombier sproc(int pid)
29bd389b36SDavid du Colombier {
30bd389b36SDavid du Colombier 	Lsym *s;
31bd389b36SDavid du Colombier 	char buf[64];
327dd7cddfSDavid du Colombier 	ulong proctab;
337dd7cddfSDavid du Colombier 	int fd, i, fcor;
34bd389b36SDavid du Colombier 
35bd389b36SDavid du Colombier 	if(symmap == 0)
36bd389b36SDavid du Colombier 		error("no map");
37bd389b36SDavid du Colombier 
38bd389b36SDavid du Colombier 	sprint(buf, "/proc/%d/mem", pid);
39bd389b36SDavid du Colombier 	fcor = open(buf, ORDWR);
40bd389b36SDavid du Colombier 	if(fcor < 0)
41bd389b36SDavid du Colombier 		error("setproc: open %s: %r", buf);
42bd389b36SDavid du Colombier 
437dd7cddfSDavid du Colombier 	checkqid(symmap->seg[0].fd, pid);
44bd389b36SDavid du Colombier 
457dd7cddfSDavid du Colombier 	if(kernel) {
467dd7cddfSDavid du Colombier 		proctab = 0;
477dd7cddfSDavid du Colombier 		sprint(buf, "/proc/%d/proc", pid);
487dd7cddfSDavid du Colombier 		fd = open(buf, OREAD);
497dd7cddfSDavid du Colombier 		if(fd >= 0) {
507dd7cddfSDavid du Colombier 			i = read(fd, buf, sizeof(buf));
517dd7cddfSDavid du Colombier 			if(i >= 0) {
527dd7cddfSDavid du Colombier 				buf[i] = '\0';
537dd7cddfSDavid du Colombier 				proctab = strtoul(buf, 0, 0);
547dd7cddfSDavid du Colombier 			}
557dd7cddfSDavid du Colombier 			close(fd);
567dd7cddfSDavid du Colombier 		}
577dd7cddfSDavid du Colombier 		s = look("proc");
587dd7cddfSDavid du Colombier 		if(s != 0)
597dd7cddfSDavid du Colombier 			s->v->ival = proctab;
607dd7cddfSDavid du Colombier 	}
61bd389b36SDavid du Colombier 
62bd389b36SDavid du Colombier 	s = look("pid");
63bd389b36SDavid du Colombier 	s->v->ival = pid;
64bd389b36SDavid du Colombier 
657dd7cddfSDavid du Colombier 	nocore();
667dd7cddfSDavid du Colombier 	cormap = attachproc(pid, kernel, fcor, &fhdr);
67bd389b36SDavid du Colombier 	if (cormap == 0)
68*59cc4ca5SDavid du Colombier 		error("setproc: can't make coremap: %r");
697dd7cddfSDavid du Colombier 	i = findseg(cormap, "text");
707dd7cddfSDavid du Colombier 	if (i > 0)
717dd7cddfSDavid du Colombier 		cormap->seg[i].name = "*text";
727dd7cddfSDavid du Colombier 	i = findseg(cormap, "data");
737dd7cddfSDavid du Colombier 	if (i > 0)
747dd7cddfSDavid du Colombier 		cormap->seg[i].name = "*data";
75bd389b36SDavid du Colombier 	install(pid);
76bd389b36SDavid du Colombier }
77bd389b36SDavid du Colombier 
78bd389b36SDavid du Colombier int
79bd389b36SDavid du Colombier nproc(char **argv)
80bd389b36SDavid du Colombier {
81bd389b36SDavid du Colombier 	char buf[128];
82bd389b36SDavid du Colombier 	int pid, i, fd;
83bd389b36SDavid du Colombier 
84bd389b36SDavid du Colombier 	pid = fork();
85bd389b36SDavid du Colombier 	switch(pid) {
86bd389b36SDavid du Colombier 	case -1:
87bd389b36SDavid du Colombier 		error("new: fork %r");
88bd389b36SDavid du Colombier 	case 0:
89bd389b36SDavid du Colombier 		rfork(RFNAMEG|RFNOTEG);
90bd389b36SDavid du Colombier 
91bd389b36SDavid du Colombier 		sprint(buf, "/proc/%d/ctl", getpid());
92bd389b36SDavid du Colombier 		fd = open(buf, ORDWR);
93bd389b36SDavid du Colombier 		if(fd < 0)
94bd389b36SDavid du Colombier 			fatal("new: open %s: %r", buf);
95bd389b36SDavid du Colombier 		write(fd, "hang", 4);
96bd389b36SDavid du Colombier 		close(fd);
97bd389b36SDavid du Colombier 
98bd389b36SDavid du Colombier 		close(0);
99bd389b36SDavid du Colombier 		close(1);
100bd389b36SDavid du Colombier 		close(2);
101bd389b36SDavid du Colombier 		for(i = 3; i < NFD; i++)
102bd389b36SDavid du Colombier 			close(i);
103bd389b36SDavid du Colombier 
104bd389b36SDavid du Colombier 		open("/dev/cons", OREAD);
105bd389b36SDavid du Colombier 		open("/dev/cons", OWRITE);
106bd389b36SDavid du Colombier 		open("/dev/cons", OWRITE);
107bd389b36SDavid du Colombier 		exec(argv[0], argv);
108bd389b36SDavid du Colombier 		fatal("new: exec %s: %r");
109bd389b36SDavid du Colombier 	default:
110bd389b36SDavid du Colombier 		install(pid);
111bd389b36SDavid du Colombier 		msg(pid, "waitstop");
112bd389b36SDavid du Colombier 		notes(pid);
113bd389b36SDavid du Colombier 		sproc(pid);
114bd389b36SDavid du Colombier 		dostop(pid);
115bd389b36SDavid du Colombier 		break;
116bd389b36SDavid du Colombier 	}
117bd389b36SDavid du Colombier 
118bd389b36SDavid du Colombier 	return pid;
119bd389b36SDavid du Colombier }
120bd389b36SDavid du Colombier 
121bd389b36SDavid du Colombier void
122bd389b36SDavid du Colombier notes(int pid)
123bd389b36SDavid du Colombier {
124bd389b36SDavid du Colombier 	Lsym *s;
125bd389b36SDavid du Colombier 	Value *v;
126bd389b36SDavid du Colombier 	int i, fd;
127bd389b36SDavid du Colombier 	char buf[128];
128bd389b36SDavid du Colombier 	List *l, **tail;
129bd389b36SDavid du Colombier 
130bd389b36SDavid du Colombier 	s = look("notes");
131bd389b36SDavid du Colombier 	if(s == 0)
132bd389b36SDavid du Colombier 		return;
133bd389b36SDavid du Colombier 	v = s->v;
134bd389b36SDavid du Colombier 
135bd389b36SDavid du Colombier 	sprint(buf, "/proc/%d/note", pid);
136bd389b36SDavid du Colombier 	fd = open(buf, OREAD);
137bd389b36SDavid du Colombier 	if(fd < 0)
138bd389b36SDavid du Colombier 		error("pid=%d: open note: %r", pid);
139bd389b36SDavid du Colombier 
140bd389b36SDavid du Colombier 	v->set = 1;
141bd389b36SDavid du Colombier 	v->type = TLIST;
142bd389b36SDavid du Colombier 	v->l = 0;
143bd389b36SDavid du Colombier 	tail = &v->l;
144bd389b36SDavid du Colombier 	for(;;) {
145bd389b36SDavid du Colombier 		i = read(fd, buf, sizeof(buf));
146bd389b36SDavid du Colombier 		if(i <= 0)
147bd389b36SDavid du Colombier 			break;
148bd389b36SDavid du Colombier 		buf[i] = '\0';
149bd389b36SDavid du Colombier 		l = al(TSTRING);
150bd389b36SDavid du Colombier 		l->string = strnode(buf);
151bd389b36SDavid du Colombier 		l->fmt = 's';
152bd389b36SDavid du Colombier 		*tail = l;
153bd389b36SDavid du Colombier 		tail = &l->next;
154bd389b36SDavid du Colombier 	}
155bd389b36SDavid du Colombier 	close(fd);
156bd389b36SDavid du Colombier }
157bd389b36SDavid du Colombier 
158bd389b36SDavid du Colombier void
159bd389b36SDavid du Colombier dostop(int pid)
160bd389b36SDavid du Colombier {
161bd389b36SDavid du Colombier 	Lsym *s;
162bd389b36SDavid du Colombier 	Node *np, *p;
163bd389b36SDavid du Colombier 
164bd389b36SDavid du Colombier 	s = look("stopped");
165bd389b36SDavid du Colombier 	if(s && s->proc) {
166bd389b36SDavid du Colombier 		np = an(ONAME, ZN, ZN);
167bd389b36SDavid du Colombier 		np->sym = s;
168bd389b36SDavid du Colombier 		np->fmt = 'D';
169bd389b36SDavid du Colombier 		np->type = TINT;
170bd389b36SDavid du Colombier 		p = con(pid);
171bd389b36SDavid du Colombier 		p->fmt = 'D';
172bd389b36SDavid du Colombier 		np = an(OCALL, np, p);
173bd389b36SDavid du Colombier 		execute(np);
174bd389b36SDavid du Colombier 	}
175bd389b36SDavid du Colombier }
176bd389b36SDavid du Colombier 
177219b2ee8SDavid du Colombier static void
178bd389b36SDavid du Colombier install(int pid)
179bd389b36SDavid du Colombier {
180bd389b36SDavid du Colombier 	Lsym *s;
181bd389b36SDavid du Colombier 	List *l;
182bd389b36SDavid du Colombier 	char buf[128];
183bd389b36SDavid du Colombier 	int i, fd, new, p;
184bd389b36SDavid du Colombier 
185bd389b36SDavid du Colombier 	new = -1;
186bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
187bd389b36SDavid du Colombier 		p = ptab[i].pid;
188bd389b36SDavid du Colombier 		if(p == pid)
189bd389b36SDavid du Colombier 			return;
190bd389b36SDavid du Colombier 		if(p == 0 && new == -1)
191bd389b36SDavid du Colombier 			new = i;
192bd389b36SDavid du Colombier 	}
193bd389b36SDavid du Colombier 	if(new == -1)
194bd389b36SDavid du Colombier 		error("no free process slots");
195bd389b36SDavid du Colombier 
196bd389b36SDavid du Colombier 	sprint(buf, "/proc/%d/ctl", pid);
197bd389b36SDavid du Colombier 	fd = open(buf, OWRITE);
198bd389b36SDavid du Colombier 	if(fd < 0)
199bd389b36SDavid du Colombier 		error("pid=%d: open ctl: %r", pid);
200bd389b36SDavid du Colombier 	ptab[new].pid = pid;
201bd389b36SDavid du Colombier 	ptab[new].ctl = fd;
202bd389b36SDavid du Colombier 
203bd389b36SDavid du Colombier 	s = look("proclist");
204bd389b36SDavid du Colombier 	l = al(TINT);
205bd389b36SDavid du Colombier 	l->fmt = 'D';
206bd389b36SDavid du Colombier 	l->ival = pid;
207bd389b36SDavid du Colombier 	l->next = s->v->l;
208bd389b36SDavid du Colombier 	s->v->l = l;
209bd389b36SDavid du Colombier 	s->v->set = 1;
210bd389b36SDavid du Colombier }
211bd389b36SDavid du Colombier 
212bd389b36SDavid du Colombier void
213bd389b36SDavid du Colombier deinstall(int pid)
214bd389b36SDavid du Colombier {
215bd389b36SDavid du Colombier 	int i;
216bd389b36SDavid du Colombier 	Lsym *s;
217bd389b36SDavid du Colombier 	List *f, **d;
218bd389b36SDavid du Colombier 
219bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
220bd389b36SDavid du Colombier 		if(ptab[i].pid == pid) {
221bd389b36SDavid du Colombier 			close(ptab[i].ctl);
222bd389b36SDavid du Colombier 			ptab[i].pid = 0;
223bd389b36SDavid du Colombier 			s = look("proclist");
224bd389b36SDavid du Colombier 			d = &s->v->l;
225bd389b36SDavid du Colombier 			for(f = *d; f; f = f->next) {
226bd389b36SDavid du Colombier 				if(f->ival == pid) {
227bd389b36SDavid du Colombier 					*d = f->next;
228bd389b36SDavid du Colombier 					break;
229bd389b36SDavid du Colombier 				}
230bd389b36SDavid du Colombier 			}
231bd389b36SDavid du Colombier 			s = look("pid");
232bd389b36SDavid du Colombier 			if(s->v->ival == pid)
233bd389b36SDavid du Colombier 				s->v->ival = 0;
234bd389b36SDavid du Colombier 			return;
235bd389b36SDavid du Colombier 		}
236bd389b36SDavid du Colombier 	}
237bd389b36SDavid du Colombier }
238bd389b36SDavid du Colombier 
239bd389b36SDavid du Colombier void
240bd389b36SDavid du Colombier msg(int pid, char *msg)
241bd389b36SDavid du Colombier {
242bd389b36SDavid du Colombier 	int i;
243bd389b36SDavid du Colombier 	int l;
244bd389b36SDavid du Colombier 	char err[ERRLEN];
245bd389b36SDavid du Colombier 
246bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
247bd389b36SDavid du Colombier 		if(ptab[i].pid == pid) {
248bd389b36SDavid du Colombier 			l = strlen(msg);
249bd389b36SDavid du Colombier 			if(write(ptab[i].ctl, msg, l) != l) {
250bd389b36SDavid du Colombier 				errstr(err);
251bd389b36SDavid du Colombier 				if(strcmp(err, "process exited") == 0)
252bd389b36SDavid du Colombier 					deinstall(pid);
253bd389b36SDavid du Colombier 				error("msg: pid=%d %s: %s", pid, msg, err);
254bd389b36SDavid du Colombier 			}
255bd389b36SDavid du Colombier 			return;
256bd389b36SDavid du Colombier 		}
257bd389b36SDavid du Colombier 	}
258bd389b36SDavid du Colombier 	error("msg: pid=%d: not found for %s", pid, msg);
259bd389b36SDavid du Colombier }
260219b2ee8SDavid du Colombier 
261219b2ee8SDavid du Colombier char *
262219b2ee8SDavid du Colombier getstatus(int pid)
263219b2ee8SDavid du Colombier {
264219b2ee8SDavid du Colombier 	int fd;
265219b2ee8SDavid du Colombier 	char *p;
266219b2ee8SDavid du Colombier 
267219b2ee8SDavid du Colombier 	static char buf[128];
268219b2ee8SDavid du Colombier 
269219b2ee8SDavid du Colombier 	sprint(buf, "/proc/%d/status", pid);
270219b2ee8SDavid du Colombier 	fd = open(buf, OREAD);
271219b2ee8SDavid du Colombier 	if(fd < 0)
272219b2ee8SDavid du Colombier 		error("open %s: %r", buf);
273219b2ee8SDavid du Colombier 	read(fd, buf, sizeof(buf));
274219b2ee8SDavid du Colombier 	close(fd);
275219b2ee8SDavid du Colombier 	p = buf+56+12;			/* Do better! */
276219b2ee8SDavid du Colombier 	while(*p == ' ')
277219b2ee8SDavid du Colombier 		p--;
278219b2ee8SDavid du Colombier 	p[1] = '\0';
279219b2ee8SDavid du Colombier 	return buf+56;			/* ditto */
280219b2ee8SDavid du Colombier }
281219b2ee8SDavid du Colombier 
282219b2ee8SDavid du Colombier char *
283219b2ee8SDavid du Colombier waitfor(int pid)
284219b2ee8SDavid du Colombier {
285219b2ee8SDavid du Colombier 	int n;
286219b2ee8SDavid du Colombier 
287219b2ee8SDavid du Colombier 	static Waitmsg w;
288219b2ee8SDavid du Colombier 
289219b2ee8SDavid du Colombier 	for(;;) {
290219b2ee8SDavid du Colombier 		n = wait(&w);
291219b2ee8SDavid du Colombier 		if(n < 0)
292219b2ee8SDavid du Colombier 			error("wait %r");
293219b2ee8SDavid du Colombier 		if(n == pid)
294219b2ee8SDavid du Colombier 			return w.msg;
295219b2ee8SDavid du Colombier 	}
296219b2ee8SDavid du Colombier }
297