trc: implement and document <>{cmd} notation - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 38b62735e4e151b626c46dd284d19fb6b0b3f59b
 (DIR) parent 7a7e8ed6b227902528cf8a6bc594bee842d0ea90
 (HTM) Author: Michael Teichgräber <mt4swm@googlemail.com>
       Date:   Sun, 13 Sep 2009 18:26:51 -0400
       
       rc: implement and document <>{cmd} notation
       
       http://codereview.appspot.com/105061
       
       Diffstat:
         M man/man1/rc.1                       |      14 ++++++++++++++
         M src/cmd/rc/havefork.c               |      64 +++++++++++++++++++++++--------
       
       2 files changed, 61 insertions(+), 17 deletions(-)
       ---
 (DIR) diff --git a/man/man1/rc.1 b/man/man1/rc.1
       t@@ -264,6 +264,20 @@ to compare their outputs
                cmp <{old} <{new}
        .EE
        .HP
       +.BI <>{ command }
       +.br
       +The
       +.I command
       +is executed asynchronously with its standard input and
       +output each connected to a pipe.  The value of the argument
       +is a pair of file names referring to the two other ends
       +of the pipes, in the order corresponding to the symbols
       +.B <
       +and
       +.B >
       +(first the pipe connected to the command's standard output,
       +then the pipe connected to its standard input).
       +.HP
        .IB argument ^ argument
        .br
        The
 (DIR) diff --git a/src/cmd/rc/havefork.c b/src/cmd/rc/havefork.c
       t@@ -177,18 +177,33 @@ Xpipefd(void)
                int pc = p->pc, pid;
                char name[40];
                int pfd[2];
       -        int sidefd, mainfd;
       -        if(pipe(pfd)<0){
       -                Xerror("can't get pipe");
       -                return;
       +        struct { int sidefd, mainfd; } fd[2], *r, *w;
       +
       +        r = &fd[0];
       +        w = &fd[1];
       +        switch(p->code[pc].i){
       +        case READ:
       +                w = nil;
       +                break;
       +        case WRITE:
       +                r = nil;
                }
       -        if(p->code[pc].i==READ){
       -                sidefd = pfd[PWR];
       -                mainfd = pfd[PRD];
       +
       +        if(r){
       +                if(pipe(pfd)<0){
       +                        Xerror("can't get pipe");
       +                        return;
       +                }
       +                 r->sidefd = pfd[PWR];
       +                 r->mainfd = pfd[PRD];
                }
       -        else{
       -                sidefd = pfd[PRD];
       -                mainfd = pfd[PWR];
       +        if(w){
       +                if(pipe(pfd)<0){
       +                        Xerror("can't get pipe");
       +                        return;
       +                }
       +                 w->sidefd = pfd[PRD];
       +                 w->mainfd = pfd[PWR];
                }
                switch(pid = fork()){
                case -1:
       t@@ -197,17 +212,32 @@ Xpipefd(void)
                case 0:
                        clearwaitpids();
                        start(p->code, pc+2, runq->local);
       -                close(mainfd);
       -                pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
       +                if(r){
       +                        close(r->mainfd);
       +                        pushredir(ROPEN, r->sidefd, 1);
       +                }
       +                if(w){
       +                        close(w->mainfd);
       +                        pushredir(ROPEN, w->sidefd, 0);
       +                }
                        runq->ret = 0;
                        break;
                default:
                        addwaitpid(pid);
       -                close(sidefd);
       -                pushredir(ROPEN, mainfd, mainfd);        /* isn't this a noop? */
       -                strcpy(name, Fdprefix);
       -                inttoascii(name+strlen(name), mainfd);
       -                pushword(name);
       +                if(w){
       +                        close(w->sidefd);
       +                        pushredir(ROPEN, w->mainfd, w->mainfd);        /* so that Xpopredir can close it later */
       +                        strcpy(name, Fdprefix);
       +                        inttoascii(name+strlen(name), w->mainfd);
       +                        pushword(name);
       +                }
       +                if(r){
       +                        close(r->sidefd);
       +                        pushredir(ROPEN, r->mainfd, r->mainfd);
       +                        strcpy(name, Fdprefix);
       +                        inttoascii(name+strlen(name), r->mainfd);
       +                        pushword(name);
       +                }
                        p->pc = p->code[pc+1].i;
                        break;
                }