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