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 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 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 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 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 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 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 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 * 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* 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