123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- #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
- nocore(void)
- {
- int i;
- if(cormap == 0)
- return;
- for (i = 0; i < cormap->nsegs; i++)
- if (cormap->seg[i].inuse && cormap->seg[i].fd >= 0)
- close(cormap->seg[i].fd);
- free(cormap);
- cormap = 0;
- }
- void
- sproc(int pid)
- {
- Lsym *s;
- char buf[64];
- int i, fcor;
- if(symmap == 0)
- error("no map");
- snprint(buf, sizeof(buf), "/proc/%d/mem", pid);
- fcor = open(buf, ORDWR);
- if(fcor < 0)
- error("setproc: open %s: %r", buf);
- checkqid(symmap->seg[0].fd, pid);
- s = look("pid");
- s->v->ival = pid;
- nocore();
- cormap = attachproc(pid, kernel, fcor, &fhdr);
- if (cormap == 0)
- error("setproc: can't make coremap: %r");
- i = findseg(cormap, "text");
- if (i > 0)
- cormap->seg[i].name = "*text";
- i = findseg(cormap, "data");
- if (i > 0)
- cormap->seg[i].name = "*data";
- install(pid);
- }
- int
- nproc(char **argv)
- {
- char buf[128];
- int pid, i, fd;
- pid = fork();
- switch(pid) {
- case -1:
- error("new: fork %r");
- case 0:
- rfork(RFNAMEG|RFNOTEG);
- snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());
- fd = open(buf, ORDWR);
- if(fd < 0)
- fatal("new: open %s: %r", buf);
- write(fd, "hang", 4);
- close(fd);
- close(0);
- close(1);
- close(2);
- for(i = 3; i < NFD; i++)
- close(i);
- open("/dev/cons", OREAD);
- open("/dev/cons", OWRITE);
- open("/dev/cons", OWRITE);
- exec(argv[0], argv);
- fatal("new: exec %s: %r");
- default:
- install(pid);
- msg(pid, "waitstop");
- notes(pid);
- sproc(pid);
- dostop(pid);
- break;
- }
- return pid;
- }
- void
- notes(int pid)
- {
- Lsym *s;
- Value *v;
- int i, fd;
- char buf[128];
- List *l, **tail;
- s = look("notes");
- if(s == 0)
- return;
- v = s->v;
- snprint(buf, sizeof(buf), "/proc/%d/note", pid);
- fd = open(buf, OREAD);
- if(fd < 0)
- error("pid=%d: open note: %r", pid);
- v->set = 1;
- v->type = TLIST;
- v->l = 0;
- tail = &v->l;
- for(;;) {
- i = read(fd, buf, sizeof(buf));
- if(i <= 0)
- break;
- buf[i] = '\0';
- l = al(TSTRING);
- l->string = strnode(buf);
- l->fmt = 's';
- *tail = l;
- tail = &l->next;
- }
- close(fd);
- }
- 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->fmt = 'D';
- np->type = TINT;
- p = con(pid);
- p->fmt = 'D';
- np = an(OCALL, np, p);
- execute(np);
- }
- }
- static void
- install(int pid)
- {
- Lsym *s;
- List *l;
- char buf[128];
- int i, fd, 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");
- snprint(buf, sizeof(buf), "/proc/%d/ctl", pid);
- fd = open(buf, OWRITE);
- if(fd < 0)
- error("pid=%d: open ctl: %r", pid);
- ptab[new].pid = pid;
- ptab[new].ctl = fd;
- s = look("proclist");
- l = al(TINT);
- l->fmt = 'D';
- l->ival = pid;
- l->next = s->v->l;
- s->v->l = l;
- s->v->set = 1;
- }
- void
- deinstall(int pid)
- {
- int i;
- Lsym *s;
- List *f, **d;
- for(i = 0; i < Maxproc; i++) {
- if(ptab[i].pid == pid) {
- close(ptab[i].ctl);
- ptab[i].pid = 0;
- s = look("proclist");
- d = &s->v->l;
- for(f = *d; f; f = f->next) {
- if(f->ival == pid) {
- *d = f->next;
- break;
- }
- }
- s = look("pid");
- if(s->v->ival == pid)
- s->v->ival = 0;
- return;
- }
- }
- }
- void
- msg(int pid, char *msg)
- {
- int i;
- int l;
- char err[ERRMAX];
- for(i = 0; i < Maxproc; i++) {
- if(ptab[i].pid == pid) {
- l = strlen(msg);
- if(write(ptab[i].ctl, msg, l) != l) {
- 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)
- {
- int fd, n;
- char *argv[16], buf[64];
- static char status[128];
- snprint(buf, sizeof(buf), "/proc/%d/status", pid);
- fd = open(buf, OREAD);
- if(fd < 0)
- error("open %s: %r", buf);
- n = read(fd, status, sizeof(status)-1);
- close(fd);
- if(n <= 0)
- error("read %s: %r", buf);
- status[n] = '\0';
- if(tokenize(status, argv, nelem(argv)-1) < 3)
- error("tokenize %s: %r", buf);
- return argv[2];
- }
- Waitmsg*
- waitfor(int pid)
- {
- Waitmsg *w;
- for(;;) {
- if((w = wait()) == nil)
- error("wait %r");
- if(w->pid == pid)
- return w;
- free(w);
- }
- }
|