From 38b62735e4e151b626c46dd284d19fb6b0b3f59b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Teichgr=C3=A4ber?= Date: Sun, 13 Sep 2009 18:26:51 -0400 Subject: rc: implement and document <>{cmd} notation http://codereview.appspot.com/105061 --- man/man1/rc.1 | 14 +++++++++++ src/cmd/rc/havefork.c | 64 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/man/man1/rc.1 b/man/man1/rc.1 index 3f9eb056..228d78ce 100644 --- a/man/man1/rc.1 +++ b/man/man1/rc.1 @@ -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 diff --git a/src/cmd/rc/havefork.c b/src/cmd/rc/havefork.c index 62d52c2c..74abfe17 100644 --- a/src/cmd/rc/havefork.c +++ b/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; } -- cgit v1.2.3