rc: implement and document <>{cmd} notation

http://codereview.appspot.com/105061
This commit is contained in:
Michael Teichgräber 2009-09-13 18:26:51 -04:00
parent 7a7e8ed6b2
commit 38b62735e4
2 changed files with 61 additions and 17 deletions

View file

@ -264,6 +264,20 @@ to compare their outputs
cmp <{old} <{new} cmp <{old} <{new}
.EE .EE
.HP .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 .IB argument ^ argument
.br .br
The The

View file

@ -177,18 +177,33 @@ Xpipefd(void)
int pc = p->pc, pid; int pc = p->pc, pid;
char name[40]; char name[40];
int pfd[2]; int pfd[2];
int sidefd, mainfd; struct { int sidefd, mainfd; } fd[2], *r, *w;
if(pipe(pfd)<0){
Xerror("can't get pipe"); r = &fd[0];
return; 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]; if(r){
mainfd = pfd[PRD]; if(pipe(pfd)<0){
Xerror("can't get pipe");
return;
}
r->sidefd = pfd[PWR];
r->mainfd = pfd[PRD];
} }
else{ if(w){
sidefd = pfd[PRD]; if(pipe(pfd)<0){
mainfd = pfd[PWR]; Xerror("can't get pipe");
return;
}
w->sidefd = pfd[PRD];
w->mainfd = pfd[PWR];
} }
switch(pid = fork()){ switch(pid = fork()){
case -1: case -1:
@ -197,17 +212,32 @@ Xpipefd(void)
case 0: case 0:
clearwaitpids(); clearwaitpids();
start(p->code, pc+2, runq->local); start(p->code, pc+2, runq->local);
close(mainfd); if(r){
pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0); close(r->mainfd);
pushredir(ROPEN, r->sidefd, 1);
}
if(w){
close(w->mainfd);
pushredir(ROPEN, w->sidefd, 0);
}
runq->ret = 0; runq->ret = 0;
break; break;
default: default:
addwaitpid(pid); addwaitpid(pid);
close(sidefd); if(w){
pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */ close(w->sidefd);
strcpy(name, Fdprefix); pushredir(ROPEN, w->mainfd, w->mainfd); /* so that Xpopredir can close it later */
inttoascii(name+strlen(name), mainfd); strcpy(name, Fdprefix);
pushword(name); 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; p->pc = p->code[pc+1].i;
break; break;
} }