]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/ratrace.c
ip/ipconfig: format ipmask with %M instead of %I
[plan9front.git] / sys / src / cmd / ratrace.c
index 7932b21609d56c4c1d677ef680661674e533db06..81b2437b11a7b6d5fde2768cd1495a3062261c91 100644 (file)
@@ -4,59 +4,74 @@
 
 enum {
        Stacksize       = 8*1024,
-       Bufsize         = 8*1024,
 };
 
 Channel *out;
 Channel *quit;
 Channel *forkc;
-int nread = 0;
+int readers = 1;
 
 typedef struct Msg Msg;
 struct Msg {
-       char    *buf;
        int     pid;
+       char    buf[8*1024];
+};
+
+typedef struct Reader Reader;
+struct Reader {
+       int     pid;
+
+       int     tfd;
+       int     cfd;
+
+       Msg*    msg;
 };
 
 void
-die(char *s)
+die(Reader *r)
 {
-       fprint(2, "%s\n", s);
-       exits(s);
+       Msg *s;
+
+       s = r->msg;
+       snprint(s->buf, sizeof(s->buf), " = %r\n");
+       s->pid = r->pid;
+       sendp(quit, s);
+       if(r->tfd >= 0)
+               close(r->tfd);
+       if(r->cfd >= 0)
+               close(r->cfd);
+       threadexits(nil);
 }
 
 void
-cwrite(int fd, char *path, char *cmd, int len)
+cwrite(Reader *r, char *cmd)
 {
-       if (write(fd, cmd, len) < len) {
-               fprint(2, "cwrite: %s: failed %d bytes: %r\n", path, len);
-               sendp(quit, nil);
-               threadexits(nil);
-       }
+       if (write(r->cfd, cmd, strlen(cmd)) < 0)
+               die(r);
 }
 
 void
 reader(void *v)
 {
-       int cfd, tfd, forking = 0, pid, newpid;
-       char *ctl, *truss;
+       int forking = 0, newpid;
+       Reader r;
        Msg *s;
 
-       pid = (int)(uintptr)v;
-       ctl = smprint("/proc/%d/ctl", pid);
-       if ((cfd = open(ctl, OWRITE)) < 0)
-               die(smprint("%s: %r", ctl));
-       truss = smprint("/proc/%d/syscall", pid);
-       if ((tfd = open(truss, OREAD)) < 0)
-               die(smprint("%s: %r", truss));
-
-       cwrite(cfd, ctl, "stop", 4);
-       cwrite(cfd, truss, "startsyscall", 12);
-
-       s = mallocz(sizeof(Msg) + Bufsize, 1);
-       s->pid = pid;
-       s->buf = (char *)&s[1];
-       while(pread(tfd, s->buf, Bufsize - 1, 0) > 0){
+       r.pid = (int)(uintptr)v;
+       r.tfd = r.cfd = -1;
+
+       r.msg = s = mallocz(sizeof(Msg), 1);
+       snprint(s->buf, sizeof(s->buf), "/proc/%d/ctl", r.pid);
+       if ((r.cfd = open(s->buf, OWRITE)) < 0)
+               die(&r);
+       snprint(s->buf, sizeof(s->buf), "/proc/%d/syscall", r.pid);
+       if ((r.tfd = open(s->buf, OREAD)) < 0)
+               die(&r);
+
+       cwrite(&r, "stop");
+       cwrite(&r, "startsyscall");
+
+       while(pread(r.tfd, s->buf, sizeof(s->buf)-1, 0) > 0){
                if (forking && s->buf[1] == '=' && s->buf[3] != '-') {
                        forking = 0;
                        newpid = strtol(&s->buf[3], 0, 0);
@@ -82,28 +97,26 @@ reader(void *v)
                        }
                        free(rf);
                }
+               s->pid = r.pid;
                sendp(out, s);
-               cwrite(cfd, truss, "startsyscall", 12);
-               s = mallocz(sizeof(Msg) + Bufsize, 1);
-               s->pid = pid;
-               s->buf = (char *)&s[1];
+
+               r.msg = s = mallocz(sizeof(Msg), 1);
+               cwrite(&r, "startsyscall");
        }
-       sendp(quit, nil);
-       threadexitsall(nil);
+       die(&r);
 }
 
 void
-writer(void *arg)
+writer(int lastpid)
 {
-       int lastpid;
+       char lastc = -1;
        Alt a[4];
        Msg *s;
-
-       lastpid = (int)(uintptr)arg;
+       int n;
 
        a[0].op = CHANRCV;
        a[0].c = quit;
-       a[0].v = nil;
+       a[0].v = &s;
        a[1].op = CHANRCV;
        a[1].c = out;
        a[1].v = &s;
@@ -112,34 +125,39 @@ writer(void *arg)
        a[2].v = nil;
        a[3].op = CHANEND;
 
-       for(;;)
+       while(readers > 0){
                switch(alt(a)){
                case 0:
-                       nread--;
-                       if(nread <= 0)
-                               goto done;
-                       break;
+                       readers--;
                case 1:
                        if(s->pid != lastpid){
                                lastpid = s->pid;
-                               fprint(2, s->buf[1]=='='? "\n%d ...": "\n", lastpid);
+                               if(lastc != '\n'){
+                                       lastc = '\n';
+                                       write(2, &lastc, 1);
+                               }
+                               if(s->buf[1] == '=')
+                                       fprint(2, "%d ...", lastpid);
+                       }
+                       n = strlen(s->buf);
+                       if(n > 0){
+                               write(2, s->buf, n);
+                               lastc = s->buf[n-1];
                        }
-                       fprint(2, "%s", s->buf);
                        free(s);
                        break;
                case 2:
-                       nread++;
+                       readers++;
                        break;
                }
-done:
-       exits(nil);
+       }
 }
 
 void
 usage(void)
 {
        fprint(2, "Usage: ratrace [-c cmd [arg...]] | [pid]\n");
-       exits("usage");
+       threadexits("usage");
 }
 
 void
@@ -174,6 +192,7 @@ threadmain(int argc, char **argv)
                if (pid < 0)
                        sysfatal("fork failed: %r");
                if(pid == 0) {
+                       write(open(smprint("/proc/%d/ctl", getpid()), OWRITE|OCEXEC), "hang", 4);
                        exec(cmd, args);
                        if(cmd[0] != '/')
                                exec(smprint("/bin/%s", cmd), args);
@@ -185,10 +204,11 @@ threadmain(int argc, char **argv)
                pid = atoi(argv[1]);
        }
 
-       out   = chancreate(sizeof(char*), 0);
-       quit  = chancreate(sizeof(char*), 0);
-       forkc = chancreate(sizeof(ulong *), 0);
-       nread++;
-       procrfork(writer, (void*)pid, Stacksize, 0);
-       reader((void*)pid);
+       out   = chancreate(sizeof(Msg*), 0);
+       quit  = chancreate(sizeof(Msg*), 0);
+       forkc = chancreate(sizeof(void*), 0);
+       procrfork(reader, (void*)pid, Stacksize, 0);
+
+       writer(pid);
+       threadexits(nil);
 }