| #include <u.h> |
| #include <libc.h> |
| #include <bio.h> |
| #include <ctype.h> |
| #include <mach.h> |
| #define Extern extern |
| #include "acid.h" |
| #include "y.tab.h" |
| |
| static void install(int); |
| |
| void |
| sproc(int xpid) |
| { |
| Lsym *s; |
| int i; |
| Regs *regs; |
| |
| if(symmap == 0) |
| error("no map"); |
| |
| if(pid == xpid) |
| return; |
| |
| if(corhdr){ |
| regs = coreregs(corhdr, xpid); |
| if(regs == nil) |
| error("no such pid in core dump"); |
| free(correg); |
| correg = regs; |
| }else{ |
| /* XXX should only change register set here if cormap already mapped */ |
| if(xpid <= 0) |
| error("bad pid"); |
| unmapproc(cormap); |
| unmapfile(corhdr, cormap); |
| free(correg); |
| correg = nil; |
| pid = -1; |
| corpid = -1; |
| |
| if(mapproc(xpid, cormap, &correg) < 0) |
| error("setproc %d: %r", xpid); |
| |
| /* XXX check text file here? */ |
| |
| for(i=0; i<cormap->nseg; i++){ |
| if(cormap->seg[i].file == nil){ |
| if(strcmp(cormap->seg[i].name, "data") == 0) |
| cormap->seg[i].name = "*data"; |
| if(strcmp(cormap->seg[i].name, "text") == 0) |
| cormap->seg[i].name = "*text"; |
| } |
| } |
| } |
| pid = xpid; |
| corpid = pid; |
| s = look("pid"); |
| s->v->store.u.ival = pid; |
| |
| install(pid); |
| } |
| |
| int |
| nproc(char **argv) |
| { |
| int pid, i; |
| |
| pid = fork(); |
| switch(pid) { |
| case -1: |
| error("new: fork %r"); |
| case 0: |
| rfork(RFNAMEG|RFNOTEG); |
| if(ctlproc(getpid(), "hang") < 0) |
| fatal("new: hang %d: %r", getpid()); |
| |
| close(0); |
| close(1); |
| close(2); |
| for(i = 3; i < NFD; i++) |
| close(i); |
| |
| open("/dev/tty", OREAD); |
| open("/dev/tty", OWRITE); |
| open("/dev/tty", OWRITE); |
| execv(argv[0], argv); |
| fatal("new: exec %s: %r", argv[0]); |
| default: |
| install(pid); |
| msg(pid, "attached"); |
| msg(pid, "waitstop"); |
| notes(pid); |
| sproc(pid); |
| dostop(pid); |
| break; |
| } |
| |
| return pid; |
| } |
| |
| void |
| notes(int pid) |
| { |
| Lsym *s; |
| Value *v; |
| int i, n; |
| char **notes; |
| List *l, **tail; |
| |
| s = look("notes"); |
| if(s == 0) |
| return; |
| |
| v = s->v; |
| n = procnotes(pid, ¬es); |
| if(n < 0) |
| error("procnotes pid=%d: %r", pid); |
| |
| v->set = 1; |
| v->type = TLIST; |
| v->store.u.l = 0; |
| tail = &v->store.u.l; |
| for(i=0; i<n; i++) { |
| l = al(TSTRING); |
| l->store.u.string = strnode(notes[i]); |
| l->store.fmt = 's'; |
| *tail = l; |
| tail = &l->next; |
| } |
| free(notes); |
| } |
| |
| void |
| dostop(int pid) |
| { |
| Lsym *s; |
| Node *np, *p; |
| |
| s = look("stopped"); |
| if(s && s->proc) { |
| np = an(ONAME, ZN, ZN); |
| np->sym = s; |
| np->store.fmt = 'D'; |
| np->type = TINT; |
| p = con(pid); |
| p->store.fmt = 'D'; |
| np = an(OCALL, np, p); |
| execute(np); |
| } |
| } |
| |
| static void |
| install(int pid) |
| { |
| Lsym *s; |
| List *l; |
| int i, new, p; |
| |
| new = -1; |
| for(i = 0; i < Maxproc; i++) { |
| p = ptab[i].pid; |
| if(p == pid) |
| return; |
| if(p == 0 && new == -1) |
| new = i; |
| } |
| if(new == -1) |
| error("no free process slots"); |
| |
| ptab[new].pid = pid; |
| |
| s = look("proclist"); |
| l = al(TINT); |
| l->store.fmt = 'D'; |
| l->store.u.ival = pid; |
| l->next = s->v->store.u.l; |
| s->v->store.u.l = l; |
| s->v->set = 1; |
| } |
| |
| /* |
| static int |
| installed(int pid) |
| { |
| int i; |
| |
| for(i=0; i<Maxproc; i++) |
| if(ptab[i].pid == pid) |
| return 1; |
| return 0; |
| } |
| */ |
| |
| void |
| deinstall(int pid) |
| { |
| int i; |
| Lsym *s; |
| List *f, **d; |
| |
| for(i = 0; i < Maxproc; i++) { |
| if(ptab[i].pid == pid) { |
| detachproc(pid); |
| /* close(ptab[i].ctl); */ |
| ptab[i].pid = 0; |
| s = look("proclist"); |
| d = &s->v->store.u.l; |
| for(f = *d; f; f = f->next) { |
| if(f->store.u.ival == pid) { |
| *d = f->next; |
| break; |
| } |
| } |
| s = look("pid"); |
| if(s->v->store.u.ival == pid) |
| s->v->store.u.ival = 0; |
| return; |
| } |
| } |
| } |
| |
| void |
| msg(int pid, char *msg) |
| { |
| int i; |
| char err[ERRMAX]; |
| |
| for(i = 0; i < Maxproc; i++) { |
| if(ptab[i].pid == pid) { |
| if(ctlproc(pid, msg) < 0){ |
| errstr(err, sizeof err); |
| if(strcmp(err, "process exited") == 0) |
| deinstall(pid); |
| error("msg: pid=%d %s: %s", pid, msg, err); |
| } |
| return; |
| } |
| } |
| error("msg: pid=%d: not found for %s", pid, msg); |
| } |
| |
| char * |
| getstatus(int pid) |
| { |
| return "unknown"; |
| } |
| |