xref: /plan9/sys/src/cmd/acid/proc.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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 
10*219b2ee8SDavid du Colombier static void install(int);
11*219b2ee8SDavid du Colombier 
12*219b2ee8SDavid du Colombier static void
13*219b2ee8SDavid du Colombier fixregs(Map *map)
14*219b2ee8SDavid du Colombier {
15*219b2ee8SDavid du Colombier 	Reglist *rp;
16*219b2ee8SDavid du Colombier 	Lsym *l;
17*219b2ee8SDavid du Colombier 	long flen;
18*219b2ee8SDavid du Colombier 
19*219b2ee8SDavid du Colombier 	static int doneonce;
20*219b2ee8SDavid du Colombier 
21*219b2ee8SDavid du Colombier 	switch(mach->mtype) {
22*219b2ee8SDavid du Colombier 	default:
23*219b2ee8SDavid du Colombier 	case MMIPS:
24*219b2ee8SDavid du Colombier 	case MSPARC:
25*219b2ee8SDavid du Colombier 		return;
26*219b2ee8SDavid du Colombier 	case MI386:
27*219b2ee8SDavid du Colombier 		if (doneonce)
28*219b2ee8SDavid du Colombier 			return;
29*219b2ee8SDavid du Colombier 		doneonce = 1;
30*219b2ee8SDavid du Colombier 		flen = 0;
31*219b2ee8SDavid du Colombier 		break;
32*219b2ee8SDavid du Colombier 	case M68020:
33*219b2ee8SDavid du Colombier 		if (machdata->ufixup(map, &flen) < 0)
34*219b2ee8SDavid du Colombier 			error("fixregs: %r\n");
35*219b2ee8SDavid du Colombier 		break;
36*219b2ee8SDavid du Colombier 	}
37*219b2ee8SDavid du Colombier 	for (rp = mach->reglist; rp->rname; rp++) {
38*219b2ee8SDavid du Colombier 		if ((rp->rflags&RFLT))
39*219b2ee8SDavid du Colombier 			continue;
40*219b2ee8SDavid du Colombier 		l = look(rp->rname);
41*219b2ee8SDavid du Colombier 		if(l == 0)
42*219b2ee8SDavid du Colombier 			print("lost register %s\n", rp->rname);
43*219b2ee8SDavid du Colombier 		else
44*219b2ee8SDavid du Colombier 			l->v->ival = mach->kbase+rp->roffs-flen;
45*219b2ee8SDavid du Colombier 	}
46*219b2ee8SDavid du Colombier }
47*219b2ee8SDavid du Colombier 
48bd389b36SDavid du Colombier void
49bd389b36SDavid du Colombier sproc(int pid)
50bd389b36SDavid du Colombier {
51bd389b36SDavid du Colombier 	Lsym *s;
52bd389b36SDavid du Colombier 	ulong ksp;
53bd389b36SDavid du Colombier 	char buf[64];
54bd389b36SDavid du Colombier 	int fd, fcor;
55bd389b36SDavid du Colombier 
56bd389b36SDavid du Colombier 	if(symmap == 0)
57bd389b36SDavid du Colombier 		error("no map");
58bd389b36SDavid du Colombier 
59bd389b36SDavid du Colombier 	sprint(buf, "/proc/%d/mem", pid);
60bd389b36SDavid du Colombier 	fcor = open(buf, ORDWR);
61bd389b36SDavid du Colombier 	if(fcor < 0)
62bd389b36SDavid du Colombier 		error("setproc: open %s: %r", buf);
63bd389b36SDavid du Colombier 
64bd389b36SDavid du Colombier 	checkqid(symmap->fd, pid);
65bd389b36SDavid du Colombier 
66bd389b36SDavid du Colombier 	if(cormap)
67bd389b36SDavid du Colombier 		close(cormap->fd);
68bd389b36SDavid du Colombier 
69bd389b36SDavid du Colombier 	s = look("pid");
70bd389b36SDavid du Colombier 	s->v->ival = pid;
71bd389b36SDavid du Colombier 
72bd389b36SDavid du Colombier 	sprint(buf, "/proc/%d/proc", pid);
73bd389b36SDavid du Colombier 	fd = open(buf, 0);
74bd389b36SDavid du Colombier 	if(fd >= 0){
75bd389b36SDavid du Colombier 		seek(fd, mach->kspoff, 0);
76bd389b36SDavid du Colombier 		if(read(fd, (char *)&ksp, 4L) == 4)
77bd389b36SDavid du Colombier 			mach->kbase = machdata->swal(ksp) & ~(mach->pgsize-1);
78bd389b36SDavid du Colombier 		close(fd);
79bd389b36SDavid du Colombier 	}
80bd389b36SDavid du Colombier 
81*219b2ee8SDavid du Colombier 	cormap = newmap(cormap, fcor, 3);
82bd389b36SDavid du Colombier 	if (cormap == 0)
83bd389b36SDavid du Colombier 		error("setproc: cant make coremap");
84bd389b36SDavid du Colombier 
85*219b2ee8SDavid du Colombier 	setmap(cormap, fhdr.txtaddr, fhdr.txtaddr+fhdr.txtsz, fhdr.txtaddr, "*text");
86*219b2ee8SDavid du Colombier 	setmap(cormap, fhdr.dataddr, mach->kbase&~mach->ktmask, fhdr.dataddr, "*data");
87*219b2ee8SDavid du Colombier 	setmap(cormap, mach->kbase, mach->kbase+mach->pgsize, mach->kbase, "*ublock");
88bd389b36SDavid du Colombier 	install(pid);
89*219b2ee8SDavid du Colombier 	fixregs(cormap);
90bd389b36SDavid du Colombier }
91bd389b36SDavid du Colombier 
92bd389b36SDavid du Colombier int
93bd389b36SDavid du Colombier nproc(char **argv)
94bd389b36SDavid du Colombier {
95bd389b36SDavid du Colombier 	char buf[128];
96bd389b36SDavid du Colombier 	int pid, i, fd;
97bd389b36SDavid du Colombier 
98bd389b36SDavid du Colombier 	pid = fork();
99bd389b36SDavid du Colombier 	switch(pid) {
100bd389b36SDavid du Colombier 	case -1:
101bd389b36SDavid du Colombier 		error("new: fork %r");
102bd389b36SDavid du Colombier 	case 0:
103bd389b36SDavid du Colombier 		rfork(RFNAMEG|RFNOTEG);
104bd389b36SDavid du Colombier 
105bd389b36SDavid du Colombier 		sprint(buf, "/proc/%d/ctl", getpid());
106bd389b36SDavid du Colombier 		fd = open(buf, ORDWR);
107bd389b36SDavid du Colombier 		if(fd < 0)
108bd389b36SDavid du Colombier 			fatal("new: open %s: %r", buf);
109bd389b36SDavid du Colombier 		write(fd, "hang", 4);
110bd389b36SDavid du Colombier 		close(fd);
111bd389b36SDavid du Colombier 
112bd389b36SDavid du Colombier 		close(0);
113bd389b36SDavid du Colombier 		close(1);
114bd389b36SDavid du Colombier 		close(2);
115bd389b36SDavid du Colombier 		for(i = 3; i < NFD; i++)
116bd389b36SDavid du Colombier 			close(i);
117bd389b36SDavid du Colombier 
118bd389b36SDavid du Colombier 		open("/dev/cons", OREAD);
119bd389b36SDavid du Colombier 		open("/dev/cons", OWRITE);
120bd389b36SDavid du Colombier 		open("/dev/cons", OWRITE);
121bd389b36SDavid du Colombier 		exec(argv[0], argv);
122bd389b36SDavid du Colombier 		fatal("new: exec %s: %r");
123bd389b36SDavid du Colombier 	default:
124bd389b36SDavid du Colombier 		install(pid);
125bd389b36SDavid du Colombier 		msg(pid, "waitstop");
126bd389b36SDavid du Colombier 		notes(pid);
127bd389b36SDavid du Colombier 		sproc(pid);
128bd389b36SDavid du Colombier 		dostop(pid);
129bd389b36SDavid du Colombier 		break;
130bd389b36SDavid du Colombier 	}
131bd389b36SDavid du Colombier 
132bd389b36SDavid du Colombier 	return pid;
133bd389b36SDavid du Colombier }
134bd389b36SDavid du Colombier 
135bd389b36SDavid du Colombier void
136bd389b36SDavid du Colombier notes(int pid)
137bd389b36SDavid du Colombier {
138bd389b36SDavid du Colombier 	Lsym *s;
139bd389b36SDavid du Colombier 	Value *v;
140bd389b36SDavid du Colombier 	int i, fd;
141bd389b36SDavid du Colombier 	char buf[128];
142bd389b36SDavid du Colombier 	List *l, **tail;
143bd389b36SDavid du Colombier 
144bd389b36SDavid du Colombier 	s = look("notes");
145bd389b36SDavid du Colombier 	if(s == 0)
146bd389b36SDavid du Colombier 		return;
147bd389b36SDavid du Colombier 	v = s->v;
148bd389b36SDavid du Colombier 
149bd389b36SDavid du Colombier 	sprint(buf, "/proc/%d/note", pid);
150bd389b36SDavid du Colombier 	fd = open(buf, OREAD);
151bd389b36SDavid du Colombier 	if(fd < 0)
152bd389b36SDavid du Colombier 		error("pid=%d: open note: %r", pid);
153bd389b36SDavid du Colombier 
154bd389b36SDavid du Colombier 	v->set = 1;
155bd389b36SDavid du Colombier 	v->type = TLIST;
156bd389b36SDavid du Colombier 	v->l = 0;
157bd389b36SDavid du Colombier 	tail = &v->l;
158bd389b36SDavid du Colombier 	for(;;) {
159bd389b36SDavid du Colombier 		i = read(fd, buf, sizeof(buf));
160bd389b36SDavid du Colombier 		if(i <= 0)
161bd389b36SDavid du Colombier 			break;
162bd389b36SDavid du Colombier 		buf[i] = '\0';
163bd389b36SDavid du Colombier 		l = al(TSTRING);
164bd389b36SDavid du Colombier 		l->string = strnode(buf);
165bd389b36SDavid du Colombier 		l->fmt = 's';
166bd389b36SDavid du Colombier 		*tail = l;
167bd389b36SDavid du Colombier 		tail = &l->next;
168bd389b36SDavid du Colombier 	}
169bd389b36SDavid du Colombier 	close(fd);
170bd389b36SDavid du Colombier }
171bd389b36SDavid du Colombier 
172bd389b36SDavid du Colombier void
173bd389b36SDavid du Colombier dostop(int pid)
174bd389b36SDavid du Colombier {
175bd389b36SDavid du Colombier 	Lsym *s;
176bd389b36SDavid du Colombier 	Node *np, *p;
177bd389b36SDavid du Colombier 
178*219b2ee8SDavid du Colombier 	fixregs(cormap);
179bd389b36SDavid du Colombier 
180bd389b36SDavid du Colombier 	s = look("stopped");
181bd389b36SDavid du Colombier 	if(s && s->proc) {
182bd389b36SDavid du Colombier 		np = an(ONAME, ZN, ZN);
183bd389b36SDavid du Colombier 		np->sym = s;
184bd389b36SDavid du Colombier 		np->fmt = 'D';
185bd389b36SDavid du Colombier 		np->type = TINT;
186bd389b36SDavid du Colombier 		p = con(pid);
187bd389b36SDavid du Colombier 		p->fmt = 'D';
188bd389b36SDavid du Colombier 		np = an(OCALL, np, p);
189bd389b36SDavid du Colombier 		execute(np);
190bd389b36SDavid du Colombier 	}
191bd389b36SDavid du Colombier }
192bd389b36SDavid du Colombier 
193*219b2ee8SDavid du Colombier static void
194bd389b36SDavid du Colombier install(int pid)
195bd389b36SDavid du Colombier {
196bd389b36SDavid du Colombier 	Lsym *s;
197bd389b36SDavid du Colombier 	List *l;
198bd389b36SDavid du Colombier 	char buf[128];
199bd389b36SDavid du Colombier 	int i, fd, new, p;
200bd389b36SDavid du Colombier 
201bd389b36SDavid du Colombier 	new = -1;
202bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
203bd389b36SDavid du Colombier 		p = ptab[i].pid;
204bd389b36SDavid du Colombier 		if(p == pid)
205bd389b36SDavid du Colombier 			return;
206bd389b36SDavid du Colombier 		if(p == 0 && new == -1)
207bd389b36SDavid du Colombier 			new = i;
208bd389b36SDavid du Colombier 	}
209bd389b36SDavid du Colombier 	if(new == -1)
210bd389b36SDavid du Colombier 		error("no free process slots");
211bd389b36SDavid du Colombier 
212bd389b36SDavid du Colombier 	sprint(buf, "/proc/%d/ctl", pid);
213bd389b36SDavid du Colombier 	fd = open(buf, OWRITE);
214bd389b36SDavid du Colombier 	if(fd < 0)
215bd389b36SDavid du Colombier 		error("pid=%d: open ctl: %r", pid);
216bd389b36SDavid du Colombier 
217bd389b36SDavid du Colombier 	ptab[new].pid = pid;
218bd389b36SDavid du Colombier 	ptab[new].ctl = fd;
219bd389b36SDavid du Colombier 
220bd389b36SDavid du Colombier 	s = look("proclist");
221bd389b36SDavid du Colombier 	l = al(TINT);
222bd389b36SDavid du Colombier 	l->fmt = 'D';
223bd389b36SDavid du Colombier 	l->ival = pid;
224bd389b36SDavid du Colombier 	l->next = s->v->l;
225bd389b36SDavid du Colombier 	s->v->l = l;
226bd389b36SDavid du Colombier 	s->v->set = 1;
227bd389b36SDavid du Colombier }
228bd389b36SDavid du Colombier 
229bd389b36SDavid du Colombier void
230bd389b36SDavid du Colombier deinstall(int pid)
231bd389b36SDavid du Colombier {
232bd389b36SDavid du Colombier 	int i;
233bd389b36SDavid du Colombier 	Lsym *s;
234bd389b36SDavid du Colombier 	List *f, **d;
235bd389b36SDavid du Colombier 
236bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
237bd389b36SDavid du Colombier 		if(ptab[i].pid == pid) {
238bd389b36SDavid du Colombier 			close(ptab[i].ctl);
239bd389b36SDavid du Colombier 			ptab[i].pid = 0;
240bd389b36SDavid du Colombier 			s = look("proclist");
241bd389b36SDavid du Colombier 			d = &s->v->l;
242bd389b36SDavid du Colombier 			for(f = *d; f; f = f->next) {
243bd389b36SDavid du Colombier 				if(f->ival == pid) {
244bd389b36SDavid du Colombier 					*d = f->next;
245bd389b36SDavid du Colombier 					break;
246bd389b36SDavid du Colombier 				}
247bd389b36SDavid du Colombier 			}
248bd389b36SDavid du Colombier 			s = look("pid");
249bd389b36SDavid du Colombier 			if(s->v->ival == pid)
250bd389b36SDavid du Colombier 				s->v->ival = 0;
251bd389b36SDavid du Colombier 			return;
252bd389b36SDavid du Colombier 		}
253bd389b36SDavid du Colombier 	}
254bd389b36SDavid du Colombier }
255bd389b36SDavid du Colombier 
256bd389b36SDavid du Colombier void
257bd389b36SDavid du Colombier msg(int pid, char *msg)
258bd389b36SDavid du Colombier {
259bd389b36SDavid du Colombier 	int i;
260bd389b36SDavid du Colombier 	int l;
261bd389b36SDavid du Colombier 	char err[ERRLEN];
262bd389b36SDavid du Colombier 
263bd389b36SDavid du Colombier 	for(i = 0; i < Maxproc; i++) {
264bd389b36SDavid du Colombier 		if(ptab[i].pid == pid) {
265bd389b36SDavid du Colombier 			l = strlen(msg);
266bd389b36SDavid du Colombier 			if(write(ptab[i].ctl, msg, l) != l) {
267bd389b36SDavid du Colombier 				errstr(err);
268bd389b36SDavid du Colombier 				if(strcmp(err, "process exited") == 0)
269bd389b36SDavid du Colombier 					deinstall(pid);
270bd389b36SDavid du Colombier 				error("msg: pid=%d %s: %s", pid, msg, err);
271bd389b36SDavid du Colombier 			}
272bd389b36SDavid du Colombier 			return;
273bd389b36SDavid du Colombier 		}
274bd389b36SDavid du Colombier 	}
275bd389b36SDavid du Colombier 	error("msg: pid=%d: not found for %s", pid, msg);
276bd389b36SDavid du Colombier }
277*219b2ee8SDavid du Colombier 
278*219b2ee8SDavid du Colombier char *
279*219b2ee8SDavid du Colombier getstatus(int pid)
280*219b2ee8SDavid du Colombier {
281*219b2ee8SDavid du Colombier 	int fd;
282*219b2ee8SDavid du Colombier 	char *p;
283*219b2ee8SDavid du Colombier 
284*219b2ee8SDavid du Colombier 	static char buf[128];
285*219b2ee8SDavid du Colombier 
286*219b2ee8SDavid du Colombier 	sprint(buf, "/proc/%d/status", pid);
287*219b2ee8SDavid du Colombier 	fd = open(buf, OREAD);
288*219b2ee8SDavid du Colombier 	if(fd < 0)
289*219b2ee8SDavid du Colombier 		error("open %s: %r", buf);
290*219b2ee8SDavid du Colombier 	read(fd, buf, sizeof(buf));
291*219b2ee8SDavid du Colombier 	close(fd);
292*219b2ee8SDavid du Colombier 	p = buf+56+12;			/* Do better! */
293*219b2ee8SDavid du Colombier 	while(*p == ' ')
294*219b2ee8SDavid du Colombier 		p--;
295*219b2ee8SDavid du Colombier 	p[1] = '\0';
296*219b2ee8SDavid du Colombier 	return buf+56;			/* ditto */
297*219b2ee8SDavid du Colombier }
298*219b2ee8SDavid du Colombier 
299*219b2ee8SDavid du Colombier char *
300*219b2ee8SDavid du Colombier waitfor(int pid)
301*219b2ee8SDavid du Colombier {
302*219b2ee8SDavid du Colombier 	int n;
303*219b2ee8SDavid du Colombier 
304*219b2ee8SDavid du Colombier 	static Waitmsg w;
305*219b2ee8SDavid du Colombier 
306*219b2ee8SDavid du Colombier 	for(;;) {
307*219b2ee8SDavid du Colombier 		n = wait(&w);
308*219b2ee8SDavid du Colombier 		if(n < 0)
309*219b2ee8SDavid du Colombier 			error("wait %r");
310*219b2ee8SDavid du Colombier 		if(n == pid)
311*219b2ee8SDavid du Colombier 			return w.msg;
312*219b2ee8SDavid du Colombier 	}
313*219b2ee8SDavid du Colombier }
314