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
nocore(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
sproc(int pid)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
nproc(char ** argv)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
notes(int pid)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
dostop(int pid)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
install(int pid)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
deinstall(int pid)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
msg(int pid,char * msg)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 *
getstatus(int pid)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*
waitfor(int pid)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 }
280