summaryrefslogtreecommitdiff
path: root/sys/src/cmd/acid/proc.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/cmd/acid/proc.c279
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);
+ }
+}