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