xref: /plan9/sys/src/cmd/acid/proc.c (revision 4ac975e2e38b792d24bc60de7fce5e6173f046ea)
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
nocore(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
sproc(int pid)28bd389b36SDavid du Colombier sproc(int pid)
29bd389b36SDavid du Colombier {
30bd389b36SDavid du Colombier 	Lsym *s;
31bd389b36SDavid du Colombier 	char buf[64];
32*4de34a7eSDavid du Colombier 	int i, fcor;
33bd389b36SDavid du Colombier 
34bd389b36SDavid du Colombier 	if(symmap == 0)
35bd389b36SDavid du Colombier 		error("no map");
36bd389b36SDavid du Colombier 
37*4de34a7eSDavid du Colombier 	snprint(buf, sizeof(buf), "/proc/%d/mem", pid);
38bd389b36SDavid du Colombier 	fcor = open(buf, ORDWR);
39bd389b36SDavid du Colombier 	if(fcor < 0)
40bd389b36SDavid du Colombier 		error("setproc: open %s: %r", buf);
41bd389b36SDavid du Colombier 
427dd7cddfSDavid du Colombier 	checkqid(symmap->seg[0].fd, pid);
43bd389b36SDavid du Colombier 
44bd389b36SDavid du Colombier 	s = look("pid");
45bd389b36SDavid du Colombier 	s->v->ival = pid;
46bd389b36SDavid du Colombier 
477dd7cddfSDavid du Colombier 	nocore();
487dd7cddfSDavid du Colombier 	cormap = attachproc(pid, kernel, fcor, &fhdr);
49bd389b36SDavid du Colombier 	if (cormap == 0)
5059cc4ca5SDavid du Colombier 		error("setproc: can't make coremap: %r");
517dd7cddfSDavid du Colombier 	i = findseg(cormap, "text");
527dd7cddfSDavid du Colombier 	if (i > 0)
537dd7cddfSDavid du Colombier 		cormap->seg[i].name = "*text";
547dd7cddfSDavid du Colombier 	i = findseg(cormap, "data");
557dd7cddfSDavid du Colombier 	if (i > 0)
567dd7cddfSDavid du Colombier 		cormap->seg[i].name = "*data";
57bd389b36SDavid du Colombier 	install(pid);
58bd389b36SDavid du Colombier }
59bd389b36SDavid du Colombier 
60bd389b36SDavid du Colombier int
nproc(char ** argv)61bd389b36SDavid du Colombier nproc(char **argv)
62bd389b36SDavid du Colombier {
63bd389b36SDavid du Colombier 	char buf[128];
64bd389b36SDavid du Colombier 	int pid, i, fd;
65bd389b36SDavid du Colombier 
66bd389b36SDavid du Colombier 	pid = fork();
67bd389b36SDavid du Colombier 	switch(pid) {
68bd389b36SDavid du Colombier 	case -1:
69bd389b36SDavid du Colombier 		error("new: fork %r");
70bd389b36SDavid du Colombier 	case 0:
71bd389b36SDavid du Colombier 		rfork(RFNAMEG|RFNOTEG);
72bd389b36SDavid du Colombier 
73*4de34a7eSDavid du Colombier 		snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());
74bd389b36SDavid du Colombier 		fd = open(buf, ORDWR);
75bd389b36SDavid du Colombier 		if(fd < 0)
76bd389b36SDavid du Colombier 			fatal("new: open %s: %r", buf);
77bd389b36SDavid du Colombier 		write(fd, "hang", 4);
78bd389b36SDavid du Colombier 		close(fd);
79bd389b36SDavid du Colombier 
80bd389b36SDavid du Colombier 		close(0);
81bd389b36SDavid du Colombier 		close(1);
82bd389b36SDavid du Colombier 		close(2);
83bd389b36SDavid du Colombier 		for(i = 3; i < NFD; i++)
84bd389b36SDavid du Colombier 			close(i);
85bd389b36SDavid du Colombier 
86bd389b36SDavid du Colombier 		open("/dev/cons", OREAD);
87bd389b36SDavid du Colombier 		open("/dev/cons", OWRITE);
88bd389b36SDavid du Colombier 		open("/dev/cons", OWRITE);
89bd389b36SDavid du Colombier 		exec(argv[0], argv);
90bd389b36SDavid du Colombier 		fatal("new: exec %s: %r");
91bd389b36SDavid du Colombier 	default:
92bd389b36SDavid du Colombier 		install(pid);
93bd389b36SDavid du Colombier 		msg(pid, "waitstop");
94bd389b36SDavid du Colombier 		notes(pid);
95bd389b36SDavid du Colombier 		sproc(pid);
96bd389b36SDavid du Colombier 		dostop(pid);
97bd389b36SDavid du Colombier 		break;
98bd389b36SDavid du Colombier 	}
99bd389b36SDavid du Colombier 
100bd389b36SDavid du Colombier 	return pid;
101bd389b36SDavid du Colombier }
102bd389b36SDavid du Colombier 
103bd389b36SDavid du Colombier void
notes(int pid)104bd389b36SDavid du Colombier notes(int pid)
105bd389b36SDavid du Colombier {
106bd389b36SDavid du Colombier 	Lsym *s;
107bd389b36SDavid du Colombier 	Value *v;
108bd389b36SDavid du Colombier 	int i, fd;
109bd389b36SDavid du Colombier 	char buf[128];
110bd389b36SDavid du Colombier 	List *l, **tail;
111bd389b36SDavid du Colombier 
112bd389b36SDavid du Colombier 	s = look("notes");
113bd389b36SDavid du Colombier 	if(s == 0)
114bd389b36SDavid du Colombier 		return;
115bd389b36SDavid du Colombier 	v = s->v;
116bd389b36SDavid du Colombier 
117*4de34a7eSDavid du Colombier 	snprint(buf, sizeof(buf), "/proc/%d/note", pid);
118bd389b36SDavid du Colombier 	fd = open(buf, OREAD);
119bd389b36SDavid du Colombier 	if(fd < 0)
120bd389b36SDavid du Colombier 		error("pid=%d: open note: %r", pid);
121bd389b36SDavid du Colombier 
122bd389b36SDavid du Colombier 	v->set = 1;
123bd389b36SDavid du Colombier 	v->type = TLIST;
124bd389b36SDavid du Colombier 	v->l = 0;
125bd389b36SDavid du Colombier 	tail = &v->l;
126bd389b36SDavid du Colombier 	for(;;) {
127bd389b36SDavid du Colombier 		i = read(fd, buf, sizeof(buf));
128bd389b36SDavid du Colombier 		if(i <= 0)
129bd389b36SDavid du Colombier 			break;
130bd389b36SDavid du Colombier 		buf[i] = '\0';
131bd389b36SDavid du Colombier 		l = al(TSTRING);
132bd389b36SDavid du Colombier 		l->string = strnode(buf);
133bd389b36SDavid du Colombier 		l->fmt = 's';
134bd389b36SDavid du Colombier 		*tail = l;
135bd389b36SDavid du Colombier 		tail = &l->next;
136bd389b36SDavid du Colombier 	}
137bd389b36SDavid du Colombier 	close(fd);
138bd389b36SDavid du Colombier }
139bd389b36SDavid du Colombier 
140bd389b36SDavid du Colombier void
dostop(int pid)141bd389b36SDavid du Colombier dostop(int pid)
142bd389b36SDavid du Colombier {
143bd389b36SDavid du Colombier 	Lsym *s;
144bd389b36SDavid du Colombier 	Node *np, *p;
145bd389b36SDavid du Colombier 
146bd389b36SDavid du Colombier 	s = look("stopped");
147bd389b36SDavid du Colombier 	if(s && s->proc) {
148bd389b36SDavid du Colombier 		np = an(ONAME, ZN, ZN);
149bd389b36SDavid du Colombier 		np->sym = s;
150bd389b36SDavid du Colombier 		np->fmt = 'D';
151bd389b36SDavid du Colombier 		np->type = TINT;
152bd389b36SDavid du Colombier 		p = con(pid);
153bd389b36SDavid du Colombier 		p->fmt = 'D';
154bd389b36SDavid du Colombier 		np = an(OCALL, np, p);
155bd389b36SDavid du Colombier 		execute(np);
156bd389b36SDavid du Colombier 	}
157bd389b36SDavid du Colombier }
158bd389b36SDavid du Colombier 
159219b2ee8SDavid du Colombier static void
install(int pid)160bd389b36SDavid du Colombier install(int pid)
161bd389b36SDavid du Colombier {
162bd389b36SDavid du Colombier 	Lsym *s;
163bd389b36SDavid du Colombier 	List *l;
164bd389b36SDavid du Colombier 	char buf[128];
165bd389b36SDavid du Colombier 	int i, fd, new, p;
166bd389b36SDavid du Colombier 
167bd389b36SDavid du Colombier 	new = -1;
168bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
169bd389b36SDavid du Colombier 		p = ptab[i].pid;
170bd389b36SDavid du Colombier 		if(p == pid)
171bd389b36SDavid du Colombier 			return;
172bd389b36SDavid du Colombier 		if(p == 0 && new == -1)
173bd389b36SDavid du Colombier 			new = i;
174bd389b36SDavid du Colombier 	}
175bd389b36SDavid du Colombier 	if(new == -1)
176bd389b36SDavid du Colombier 		error("no free process slots");
177bd389b36SDavid du Colombier 
178*4de34a7eSDavid du Colombier 	snprint(buf, sizeof(buf), "/proc/%d/ctl", pid);
179bd389b36SDavid du Colombier 	fd = open(buf, OWRITE);
180bd389b36SDavid du Colombier 	if(fd < 0)
181bd389b36SDavid du Colombier 		error("pid=%d: open ctl: %r", pid);
182bd389b36SDavid du Colombier 	ptab[new].pid = pid;
183bd389b36SDavid du Colombier 	ptab[new].ctl = fd;
184bd389b36SDavid du Colombier 
185bd389b36SDavid du Colombier 	s = look("proclist");
186bd389b36SDavid du Colombier 	l = al(TINT);
187bd389b36SDavid du Colombier 	l->fmt = 'D';
188bd389b36SDavid du Colombier 	l->ival = pid;
189bd389b36SDavid du Colombier 	l->next = s->v->l;
190bd389b36SDavid du Colombier 	s->v->l = l;
191bd389b36SDavid du Colombier 	s->v->set = 1;
192bd389b36SDavid du Colombier }
193bd389b36SDavid du Colombier 
194bd389b36SDavid du Colombier void
deinstall(int pid)195bd389b36SDavid du Colombier deinstall(int pid)
196bd389b36SDavid du Colombier {
197bd389b36SDavid du Colombier 	int i;
198bd389b36SDavid du Colombier 	Lsym *s;
199bd389b36SDavid du Colombier 	List *f, **d;
200bd389b36SDavid du Colombier 
201bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
202bd389b36SDavid du Colombier 		if(ptab[i].pid == pid) {
203bd389b36SDavid du Colombier 			close(ptab[i].ctl);
204bd389b36SDavid du Colombier 			ptab[i].pid = 0;
205bd389b36SDavid du Colombier 			s = look("proclist");
206bd389b36SDavid du Colombier 			d = &s->v->l;
207bd389b36SDavid du Colombier 			for(f = *d; f; f = f->next) {
208bd389b36SDavid du Colombier 				if(f->ival == pid) {
209bd389b36SDavid du Colombier 					*d = f->next;
210bd389b36SDavid du Colombier 					break;
211bd389b36SDavid du Colombier 				}
212bd389b36SDavid du Colombier 			}
213bd389b36SDavid du Colombier 			s = look("pid");
214bd389b36SDavid du Colombier 			if(s->v->ival == pid)
215bd389b36SDavid du Colombier 				s->v->ival = 0;
216bd389b36SDavid du Colombier 			return;
217bd389b36SDavid du Colombier 		}
218bd389b36SDavid du Colombier 	}
219bd389b36SDavid du Colombier }
220bd389b36SDavid du Colombier 
221bd389b36SDavid du Colombier void
msg(int pid,char * msg)222bd389b36SDavid du Colombier msg(int pid, char *msg)
223bd389b36SDavid du Colombier {
224bd389b36SDavid du Colombier 	int i;
225bd389b36SDavid du Colombier 	int l;
2269a747e4fSDavid du Colombier 	char err[ERRMAX];
227bd389b36SDavid du Colombier 
228bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
229bd389b36SDavid du Colombier 		if(ptab[i].pid == pid) {
230bd389b36SDavid du Colombier 			l = strlen(msg);
231bd389b36SDavid du Colombier 			if(write(ptab[i].ctl, msg, l) != l) {
2329a747e4fSDavid du Colombier 				errstr(err, sizeof err);
233bd389b36SDavid du Colombier 				if(strcmp(err, "process exited") == 0)
234bd389b36SDavid du Colombier 					deinstall(pid);
235bd389b36SDavid du Colombier 				error("msg: pid=%d %s: %s", pid, msg, err);
236bd389b36SDavid du Colombier 			}
237bd389b36SDavid du Colombier 			return;
238bd389b36SDavid du Colombier 		}
239bd389b36SDavid du Colombier 	}
240bd389b36SDavid du Colombier 	error("msg: pid=%d: not found for %s", pid, msg);
241bd389b36SDavid du Colombier }
242219b2ee8SDavid du Colombier 
243219b2ee8SDavid du Colombier char *
getstatus(int pid)244219b2ee8SDavid du Colombier getstatus(int pid)
245219b2ee8SDavid du Colombier {
2466c0bae65SDavid du Colombier 	int fd, n;
2476c0bae65SDavid du Colombier 	char *argv[16], buf[64];
2486c0bae65SDavid du Colombier 	static char status[128];
249219b2ee8SDavid du Colombier 
250*4de34a7eSDavid du Colombier 	snprint(buf, sizeof(buf), "/proc/%d/status", pid);
251219b2ee8SDavid du Colombier 	fd = open(buf, OREAD);
252219b2ee8SDavid du Colombier 	if(fd < 0)
253219b2ee8SDavid du Colombier 		error("open %s: %r", buf);
2546c0bae65SDavid du Colombier 
2556c0bae65SDavid du Colombier 	n = read(fd, status, sizeof(status)-1);
256219b2ee8SDavid du Colombier 	close(fd);
2576c0bae65SDavid du Colombier 	if(n <= 0)
2586c0bae65SDavid du Colombier 		error("read %s: %r", buf);
2596c0bae65SDavid du Colombier 	status[n] = '\0';
2606c0bae65SDavid du Colombier 
2616c0bae65SDavid du Colombier 	if(tokenize(status, argv, nelem(argv)-1) < 3)
2626c0bae65SDavid du Colombier 		error("tokenize %s: %r", buf);
2636c0bae65SDavid du Colombier 
2646c0bae65SDavid du Colombier 	return argv[2];
265219b2ee8SDavid du Colombier }
266219b2ee8SDavid du Colombier 
2679a747e4fSDavid du Colombier Waitmsg*
waitfor(int pid)268219b2ee8SDavid du Colombier waitfor(int pid)
269219b2ee8SDavid du Colombier {
2709a747e4fSDavid du Colombier 	Waitmsg *w;
271219b2ee8SDavid du Colombier 
272219b2ee8SDavid du Colombier 	for(;;) {
2739a747e4fSDavid du Colombier 		if((w = wait()) == nil)
274219b2ee8SDavid du Colombier 			error("wait %r");
2759a747e4fSDavid du Colombier 		if(w->pid == pid)
2769a747e4fSDavid du Colombier 			return w;
2779a747e4fSDavid du Colombier 		free(w);
278219b2ee8SDavid du Colombier 	}
279219b2ee8SDavid du Colombier }
280