]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/iostats.c
abaco: cleanup, handle image/x-icon, don't use backspace as a hotkey, and remove...
[plan9front.git] / sys / src / cmd / iostats.c
index 20053ccfd1a5c2ad0e99da2fa39e4720b16d258c..be49a11b70e0e16e539ef386ec0daf82f30c6c6d 100644 (file)
@@ -262,9 +262,11 @@ main(int argc, char **argv)
        char *dbfile;
        char buf[64*1024];
        float brpsec, bwpsec, bppsec;
-       int cpid, fspid, rspid, dbg, n, mflag;
+       int cpid, fspid, expid, rspid, dbg, n, mflag;
+       char *fds[3];
+       Waitmsg *w;
        File *fs;
-       Req *r, **rr;
+       Req *r;
 
        dbg = 0;
        mflag = MREPL;
@@ -290,32 +292,43 @@ main(int argc, char **argv)
                usage();
 
        if(pipe(pfd) < 0)
-               sysfatal("pipe");
+               sysfatal("pipe: %r");
+
+       /* dup std fds to be inherited to exportfs */
+       fds[0] = smprint("/fd/%d", dup(0, -1));
+       fds[1] = smprint("/fd/%d", dup(1, -1));
+       fds[2] = smprint("/fd/%d", dup(2, -1));
 
        switch(cpid = fork()) {
        case -1:
-               sysfatal("fork");
+               sysfatal("fork: %r");
        case 0:
                close(pfd[1]);
+               close(atoi(strrchr(fds[0], '/')+1));
+               close(atoi(strrchr(fds[1], '/')+1));
+               close(atoi(strrchr(fds[2], '/')+1));
+
                if(getwd(buf, sizeof(buf)) == 0)
-                       sysfatal("no working directory");
+                       sysfatal("no working directory: %r");
 
-               rfork(RFENVG|RFNAMEG|RFNOTEG);
+               rfork(RFENVG|RFNAMEG);
 
                if(mount(pfd[0], -1, "/", mflag, "") < 0)
-                       sysfatal("mount /");
+                       sysfatal("mount /: %r");
+
+               /* replace std fds with the exported ones */
+               close(0); open(fds[0], OREAD);
+               close(1); open(fds[1], OWRITE);
+               close(2); open(fds[2], OWRITE);
 
                bind("#c/pid", "/dev/pid", MREPL);
                bind("#c/ppid", "/dev/ppid", MREPL);
                bind("#e", "/env", MREPL|MCREATE);
-               close(0);
-               close(1);
-               close(2);
-               open("/fd/0", OREAD);
-               open("/fd/1", OWRITE);
-               open("/fd/2", OWRITE);
+               bind("#d", "/fd", MREPL);
+
                if(chdir(buf) < 0)
-                       sysfatal("chdir");
+                       sysfatal("chdir: %r");
+
                exec(*argv, argv);
                if(**argv != '/' && strncmp(*argv, "./", 2) != 0 && strncmp(*argv, "../", 3) != 0)
                        exec(smprint("/bin/%s", *argv), argv);
@@ -324,44 +337,62 @@ main(int argc, char **argv)
                close(pfd[0]);
        }
 
-       switch(fspid = fork()) {
-       default:
-               while(cpid != waitpid())
-                       ;
-               postnote(PNPROC, fspid, DONESTR);
-               while(fspid != waitpid())
-                       ;
-               exits(0);
-       case -1:
-               sysfatal("fork");
-       case 0:
-               notify(catcher);
-               break;
-       }
-
+       /* isolate us from interrupts */
+       rfork(RFNOTEG);
        if(pipe(efd) < 0)
-               sysfatal("pipe");
+               sysfatal("pipe: %r");
 
        /* spawn exportfs */
-       switch(fork()) {
+       switch(expid = fork()) {
        default:
                close(efd[0]);
+               close(atoi(strrchr(fds[0], '/')+1));
+               close(atoi(strrchr(fds[1], '/')+1));
+               close(atoi(strrchr(fds[2], '/')+1));
                break;
        case -1:
-               sysfatal("fork");
+               sysfatal("fork: %r");
        case 0:
                dup(efd[0], 0);
                close(efd[0]);
                close(efd[1]);
+               close(pfd[1]);
                if(dbg){
                        execl("/bin/exportfs", "exportfs", "-df", dbfile, "-r", "/", nil);
                } else {
                        execl("/bin/exportfs", "exportfs", "-r", "/", nil);
                }
-               exits(0);
+               sysfatal("exec: %r");
        }
 
-       fmtinstall('F', fcallfmt);
+       switch(fspid = fork()) {
+       default:
+               close(pfd[1]);
+               close(efd[1]);
+
+               buf[0] = '\0';
+               while((w = wait()) != nil && (cpid != -1 || fspid != -1 || expid != -1)){
+                       if(w->pid == fspid)
+                               fspid = -1;
+                       else if(w->pid == expid)
+                               expid = -1;
+                       else if(w->pid == cpid){
+                               cpid = -1;
+                               strcpy(buf, w->msg);
+                               if(fspid != -1)
+                                       postnote(PNPROC, fspid, DONESTR);
+                       }
+                       if(buf[0] == '\0')
+                               strcpy(buf, w->msg);
+                       free(w);
+               }
+               exits(buf);
+       case -1:
+               sysfatal("fork: %r");
+       case 0:
+               notify(catcher);
+               break;
+       }
 
        stats->rpc[Tversion].name = "version";
        stats->rpc[Tauth].name = "auth";
@@ -386,6 +417,7 @@ main(int argc, char **argv)
                while(!done){
                        uchar tmp[sizeof(buf)];
                        Fcall f;
+                       Req **rr;
 
                        n = read(efd[1], buf, sizeof(buf));
                        if(n < 0)
@@ -440,7 +472,7 @@ main(int argc, char **argv)
                        if(write(pfd[1], buf, n) != n)
                                break;
                }
-               exits(0);
+               exits(nil);
        default:
                /* read request from mount and pass to exportfs */
                while(!done){
@@ -523,6 +555,14 @@ main(int argc, char **argv)
        for(fs = stats->file; fs < &stats->file[Maxfile]; fs++){
                if(fs->nopen == 0)
                        break;
+
+               if(strcmp(fs->path, fds[0]) == 0)
+                       fs->path = "stdin";
+               else if(strcmp(fs->path, fds[1]) == 0)
+                       fs->path = "stdout";
+               else if(strcmp(fs->path, fds[2]) == 0)
+                       fs->path = "stderr";
+
                fprint(2, "%5lud %8lud %8llud %8lud %8llud %s\n",
                        fs->nopen,
                        fs->nread, fs->bread,
@@ -530,5 +570,5 @@ main(int argc, char **argv)
                        fs->path);
        }
 
-       exits(0);
+       exits(nil);
 }