diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/acid/proc.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/acid/proc.c')
-rwxr-xr-x | sys/src/cmd/acid/proc.c | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/sys/src/cmd/acid/proc.c b/sys/src/cmd/acid/proc.c new file mode 100755 index 000000000..efb06d047 --- /dev/null +++ b/sys/src/cmd/acid/proc.c @@ -0,0 +1,279 @@ +#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); + } +} |