Commit Diff


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;
 	}