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 10219b2ee8SDavid du Colombier static void install(int); 11219b2ee8SDavid du Colombier 127dd7cddfSDavid du Colombier void 137dd7cddfSDavid du Colombier nocore(void) 14219b2ee8SDavid du Colombier { 157dd7cddfSDavid du Colombier int i; 16219b2ee8SDavid du Colombier 177dd7cddfSDavid du Colombier if(cormap == 0) 187dd7cddfSDavid du Colombier return; 19219b2ee8SDavid du Colombier 207dd7cddfSDavid du Colombier for (i = 0; i < cormap->nsegs; i++) 217dd7cddfSDavid du Colombier if (cormap->seg[i].inuse && cormap->seg[i].fd >= 0) 227dd7cddfSDavid du Colombier close(cormap->seg[i].fd); 237dd7cddfSDavid du Colombier free(cormap); 247dd7cddfSDavid du Colombier cormap = 0; 25219b2ee8SDavid du Colombier } 26219b2ee8SDavid du Colombier 27bd389b36SDavid du Colombier void 28bd389b36SDavid du Colombier sproc(int pid) 29bd389b36SDavid du Colombier { 30bd389b36SDavid du Colombier Lsym *s; 31bd389b36SDavid du Colombier char buf[64]; 327dd7cddfSDavid du Colombier ulong proctab; 337dd7cddfSDavid du Colombier int fd, i, fcor; 34bd389b36SDavid du Colombier 35bd389b36SDavid du Colombier if(symmap == 0) 36bd389b36SDavid du Colombier error("no map"); 37bd389b36SDavid du Colombier 38bd389b36SDavid du Colombier sprint(buf, "/proc/%d/mem", pid); 39bd389b36SDavid du Colombier fcor = open(buf, ORDWR); 40bd389b36SDavid du Colombier if(fcor < 0) 41bd389b36SDavid du Colombier error("setproc: open %s: %r", buf); 42bd389b36SDavid du Colombier 437dd7cddfSDavid du Colombier checkqid(symmap->seg[0].fd, pid); 44bd389b36SDavid du Colombier 457dd7cddfSDavid du Colombier if(kernel) { 467dd7cddfSDavid du Colombier proctab = 0; 477dd7cddfSDavid du Colombier sprint(buf, "/proc/%d/proc", pid); 487dd7cddfSDavid du Colombier fd = open(buf, OREAD); 497dd7cddfSDavid du Colombier if(fd >= 0) { 507dd7cddfSDavid du Colombier i = read(fd, buf, sizeof(buf)); 517dd7cddfSDavid du Colombier if(i >= 0) { 527dd7cddfSDavid du Colombier buf[i] = '\0'; 537dd7cddfSDavid du Colombier proctab = strtoul(buf, 0, 0); 547dd7cddfSDavid du Colombier } 557dd7cddfSDavid du Colombier close(fd); 567dd7cddfSDavid du Colombier } 577dd7cddfSDavid du Colombier s = look("proc"); 587dd7cddfSDavid du Colombier if(s != 0) 597dd7cddfSDavid du Colombier s->v->ival = proctab; 607dd7cddfSDavid du Colombier } 61bd389b36SDavid du Colombier 62bd389b36SDavid du Colombier s = look("pid"); 63bd389b36SDavid du Colombier s->v->ival = pid; 64bd389b36SDavid du Colombier 657dd7cddfSDavid du Colombier nocore(); 667dd7cddfSDavid du Colombier cormap = attachproc(pid, kernel, fcor, &fhdr); 67bd389b36SDavid du Colombier if (cormap == 0) 68*59cc4ca5SDavid du Colombier error("setproc: can't make coremap: %r"); 697dd7cddfSDavid du Colombier i = findseg(cormap, "text"); 707dd7cddfSDavid du Colombier if (i > 0) 717dd7cddfSDavid du Colombier cormap->seg[i].name = "*text"; 727dd7cddfSDavid du Colombier i = findseg(cormap, "data"); 737dd7cddfSDavid du Colombier if (i > 0) 747dd7cddfSDavid du Colombier cormap->seg[i].name = "*data"; 75bd389b36SDavid du Colombier install(pid); 76bd389b36SDavid du Colombier } 77bd389b36SDavid du Colombier 78bd389b36SDavid du Colombier int 79bd389b36SDavid du Colombier nproc(char **argv) 80bd389b36SDavid du Colombier { 81bd389b36SDavid du Colombier char buf[128]; 82bd389b36SDavid du Colombier int pid, i, fd; 83bd389b36SDavid du Colombier 84bd389b36SDavid du Colombier pid = fork(); 85bd389b36SDavid du Colombier switch(pid) { 86bd389b36SDavid du Colombier case -1: 87bd389b36SDavid du Colombier error("new: fork %r"); 88bd389b36SDavid du Colombier case 0: 89bd389b36SDavid du Colombier rfork(RFNAMEG|RFNOTEG); 90bd389b36SDavid du Colombier 91bd389b36SDavid du Colombier sprint(buf, "/proc/%d/ctl", getpid()); 92bd389b36SDavid du Colombier fd = open(buf, ORDWR); 93bd389b36SDavid du Colombier if(fd < 0) 94bd389b36SDavid du Colombier fatal("new: open %s: %r", buf); 95bd389b36SDavid du Colombier write(fd, "hang", 4); 96bd389b36SDavid du Colombier close(fd); 97bd389b36SDavid du Colombier 98bd389b36SDavid du Colombier close(0); 99bd389b36SDavid du Colombier close(1); 100bd389b36SDavid du Colombier close(2); 101bd389b36SDavid du Colombier for(i = 3; i < NFD; i++) 102bd389b36SDavid du Colombier close(i); 103bd389b36SDavid du Colombier 104bd389b36SDavid du Colombier open("/dev/cons", OREAD); 105bd389b36SDavid du Colombier open("/dev/cons", OWRITE); 106bd389b36SDavid du Colombier open("/dev/cons", OWRITE); 107bd389b36SDavid du Colombier exec(argv[0], argv); 108bd389b36SDavid du Colombier fatal("new: exec %s: %r"); 109bd389b36SDavid du Colombier default: 110bd389b36SDavid du Colombier install(pid); 111bd389b36SDavid du Colombier msg(pid, "waitstop"); 112bd389b36SDavid du Colombier notes(pid); 113bd389b36SDavid du Colombier sproc(pid); 114bd389b36SDavid du Colombier dostop(pid); 115bd389b36SDavid du Colombier break; 116bd389b36SDavid du Colombier } 117bd389b36SDavid du Colombier 118bd389b36SDavid du Colombier return pid; 119bd389b36SDavid du Colombier } 120bd389b36SDavid du Colombier 121bd389b36SDavid du Colombier void 122bd389b36SDavid du Colombier notes(int pid) 123bd389b36SDavid du Colombier { 124bd389b36SDavid du Colombier Lsym *s; 125bd389b36SDavid du Colombier Value *v; 126bd389b36SDavid du Colombier int i, fd; 127bd389b36SDavid du Colombier char buf[128]; 128bd389b36SDavid du Colombier List *l, **tail; 129bd389b36SDavid du Colombier 130bd389b36SDavid du Colombier s = look("notes"); 131bd389b36SDavid du Colombier if(s == 0) 132bd389b36SDavid du Colombier return; 133bd389b36SDavid du Colombier v = s->v; 134bd389b36SDavid du Colombier 135bd389b36SDavid du Colombier sprint(buf, "/proc/%d/note", pid); 136bd389b36SDavid du Colombier fd = open(buf, OREAD); 137bd389b36SDavid du Colombier if(fd < 0) 138bd389b36SDavid du Colombier error("pid=%d: open note: %r", pid); 139bd389b36SDavid du Colombier 140bd389b36SDavid du Colombier v->set = 1; 141bd389b36SDavid du Colombier v->type = TLIST; 142bd389b36SDavid du Colombier v->l = 0; 143bd389b36SDavid du Colombier tail = &v->l; 144bd389b36SDavid du Colombier for(;;) { 145bd389b36SDavid du Colombier i = read(fd, buf, sizeof(buf)); 146bd389b36SDavid du Colombier if(i <= 0) 147bd389b36SDavid du Colombier break; 148bd389b36SDavid du Colombier buf[i] = '\0'; 149bd389b36SDavid du Colombier l = al(TSTRING); 150bd389b36SDavid du Colombier l->string = strnode(buf); 151bd389b36SDavid du Colombier l->fmt = 's'; 152bd389b36SDavid du Colombier *tail = l; 153bd389b36SDavid du Colombier tail = &l->next; 154bd389b36SDavid du Colombier } 155bd389b36SDavid du Colombier close(fd); 156bd389b36SDavid du Colombier } 157bd389b36SDavid du Colombier 158bd389b36SDavid du Colombier void 159bd389b36SDavid du Colombier dostop(int pid) 160bd389b36SDavid du Colombier { 161bd389b36SDavid du Colombier Lsym *s; 162bd389b36SDavid du Colombier Node *np, *p; 163bd389b36SDavid du Colombier 164bd389b36SDavid du Colombier s = look("stopped"); 165bd389b36SDavid du Colombier if(s && s->proc) { 166bd389b36SDavid du Colombier np = an(ONAME, ZN, ZN); 167bd389b36SDavid du Colombier np->sym = s; 168bd389b36SDavid du Colombier np->fmt = 'D'; 169bd389b36SDavid du Colombier np->type = TINT; 170bd389b36SDavid du Colombier p = con(pid); 171bd389b36SDavid du Colombier p->fmt = 'D'; 172bd389b36SDavid du Colombier np = an(OCALL, np, p); 173bd389b36SDavid du Colombier execute(np); 174bd389b36SDavid du Colombier } 175bd389b36SDavid du Colombier } 176bd389b36SDavid du Colombier 177219b2ee8SDavid du Colombier static void 178bd389b36SDavid du Colombier install(int pid) 179bd389b36SDavid du Colombier { 180bd389b36SDavid du Colombier Lsym *s; 181bd389b36SDavid du Colombier List *l; 182bd389b36SDavid du Colombier char buf[128]; 183bd389b36SDavid du Colombier int i, fd, new, p; 184bd389b36SDavid du Colombier 185bd389b36SDavid du Colombier new = -1; 186bd389b36SDavid du Colombier for(i = 0; i < Maxproc; i++) { 187bd389b36SDavid du Colombier p = ptab[i].pid; 188bd389b36SDavid du Colombier if(p == pid) 189bd389b36SDavid du Colombier return; 190bd389b36SDavid du Colombier if(p == 0 && new == -1) 191bd389b36SDavid du Colombier new = i; 192bd389b36SDavid du Colombier } 193bd389b36SDavid du Colombier if(new == -1) 194bd389b36SDavid du Colombier error("no free process slots"); 195bd389b36SDavid du Colombier 196bd389b36SDavid du Colombier sprint(buf, "/proc/%d/ctl", pid); 197bd389b36SDavid du Colombier fd = open(buf, OWRITE); 198bd389b36SDavid du Colombier if(fd < 0) 199bd389b36SDavid du Colombier error("pid=%d: open ctl: %r", pid); 200bd389b36SDavid du Colombier ptab[new].pid = pid; 201bd389b36SDavid du Colombier ptab[new].ctl = fd; 202bd389b36SDavid du Colombier 203bd389b36SDavid du Colombier s = look("proclist"); 204bd389b36SDavid du Colombier l = al(TINT); 205bd389b36SDavid du Colombier l->fmt = 'D'; 206bd389b36SDavid du Colombier l->ival = pid; 207bd389b36SDavid du Colombier l->next = s->v->l; 208bd389b36SDavid du Colombier s->v->l = l; 209bd389b36SDavid du Colombier s->v->set = 1; 210bd389b36SDavid du Colombier } 211bd389b36SDavid du Colombier 212bd389b36SDavid du Colombier void 213bd389b36SDavid du Colombier deinstall(int pid) 214bd389b36SDavid du Colombier { 215bd389b36SDavid du Colombier int i; 216bd389b36SDavid du Colombier Lsym *s; 217bd389b36SDavid du Colombier List *f, **d; 218bd389b36SDavid du Colombier 219bd389b36SDavid du Colombier for(i = 0; i < Maxproc; i++) { 220bd389b36SDavid du Colombier if(ptab[i].pid == pid) { 221bd389b36SDavid du Colombier close(ptab[i].ctl); 222bd389b36SDavid du Colombier ptab[i].pid = 0; 223bd389b36SDavid du Colombier s = look("proclist"); 224bd389b36SDavid du Colombier d = &s->v->l; 225bd389b36SDavid du Colombier for(f = *d; f; f = f->next) { 226bd389b36SDavid du Colombier if(f->ival == pid) { 227bd389b36SDavid du Colombier *d = f->next; 228bd389b36SDavid du Colombier break; 229bd389b36SDavid du Colombier } 230bd389b36SDavid du Colombier } 231bd389b36SDavid du Colombier s = look("pid"); 232bd389b36SDavid du Colombier if(s->v->ival == pid) 233bd389b36SDavid du Colombier s->v->ival = 0; 234bd389b36SDavid du Colombier return; 235bd389b36SDavid du Colombier } 236bd389b36SDavid du Colombier } 237bd389b36SDavid du Colombier } 238bd389b36SDavid du Colombier 239bd389b36SDavid du Colombier void 240bd389b36SDavid du Colombier msg(int pid, char *msg) 241bd389b36SDavid du Colombier { 242bd389b36SDavid du Colombier int i; 243bd389b36SDavid du Colombier int l; 244bd389b36SDavid du Colombier char err[ERRLEN]; 245bd389b36SDavid du Colombier 246bd389b36SDavid du Colombier for(i = 0; i < Maxproc; i++) { 247bd389b36SDavid du Colombier if(ptab[i].pid == pid) { 248bd389b36SDavid du Colombier l = strlen(msg); 249bd389b36SDavid du Colombier if(write(ptab[i].ctl, msg, l) != l) { 250bd389b36SDavid du Colombier errstr(err); 251bd389b36SDavid du Colombier if(strcmp(err, "process exited") == 0) 252bd389b36SDavid du Colombier deinstall(pid); 253bd389b36SDavid du Colombier error("msg: pid=%d %s: %s", pid, msg, err); 254bd389b36SDavid du Colombier } 255bd389b36SDavid du Colombier return; 256bd389b36SDavid du Colombier } 257bd389b36SDavid du Colombier } 258bd389b36SDavid du Colombier error("msg: pid=%d: not found for %s", pid, msg); 259bd389b36SDavid du Colombier } 260219b2ee8SDavid du Colombier 261219b2ee8SDavid du Colombier char * 262219b2ee8SDavid du Colombier getstatus(int pid) 263219b2ee8SDavid du Colombier { 264219b2ee8SDavid du Colombier int fd; 265219b2ee8SDavid du Colombier char *p; 266219b2ee8SDavid du Colombier 267219b2ee8SDavid du Colombier static char buf[128]; 268219b2ee8SDavid du Colombier 269219b2ee8SDavid du Colombier sprint(buf, "/proc/%d/status", pid); 270219b2ee8SDavid du Colombier fd = open(buf, OREAD); 271219b2ee8SDavid du Colombier if(fd < 0) 272219b2ee8SDavid du Colombier error("open %s: %r", buf); 273219b2ee8SDavid du Colombier read(fd, buf, sizeof(buf)); 274219b2ee8SDavid du Colombier close(fd); 275219b2ee8SDavid du Colombier p = buf+56+12; /* Do better! */ 276219b2ee8SDavid du Colombier while(*p == ' ') 277219b2ee8SDavid du Colombier p--; 278219b2ee8SDavid du Colombier p[1] = '\0'; 279219b2ee8SDavid du Colombier return buf+56; /* ditto */ 280219b2ee8SDavid du Colombier } 281219b2ee8SDavid du Colombier 282219b2ee8SDavid du Colombier char * 283219b2ee8SDavid du Colombier waitfor(int pid) 284219b2ee8SDavid du Colombier { 285219b2ee8SDavid du Colombier int n; 286219b2ee8SDavid du Colombier 287219b2ee8SDavid du Colombier static Waitmsg w; 288219b2ee8SDavid du Colombier 289219b2ee8SDavid du Colombier for(;;) { 290219b2ee8SDavid du Colombier n = wait(&w); 291219b2ee8SDavid du Colombier if(n < 0) 292219b2ee8SDavid du Colombier error("wait %r"); 293219b2ee8SDavid du Colombier if(n == pid) 294219b2ee8SDavid du Colombier return w.msg; 295219b2ee8SDavid du Colombier } 296219b2ee8SDavid du Colombier } 297