commit 38b62735e4e151b626c46dd284d19fb6b0b3f59b from: Michael Teichgräber date: Sun Sep 13 22:26:51 2009 UTC rc: implement and document <>{cmd} notation http://codereview.appspot.com/105061 commit - 7a7e8ed6b227902528cf8a6bc594bee842d0ea90 commit + 38b62735e4e151b626c46dd284d19fb6b0b3f59b blob - 3f9eb0563ce67e21317b7d2d4213c16f9216e803 blob + 228d78ceac39641054e4395ec2eacb71fc7eab43 --- man/man1/rc.1 +++ man/man1/rc.1 @@ -263,6 +263,20 @@ to compare their outputs .EX 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 blob - 62d52c2cf37913abd714912f0b2e7540461583f2 blob + 74abfe17cb8fb17f73d1f321517bff13c7de83b5 --- src/cmd/rc/havefork.c +++ src/cmd/rc/havefork.c @@ -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: @@ -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; }