rc: implement and document <>{cmd} notation
http://codereview.appspot.com/105061
This commit is contained in:
parent
7a7e8ed6b2
commit
38b62735e4
2 changed files with 61 additions and 17 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue