Commit Diff


commit - ca30274bd90f09b6d19d36b87278fdb40efddada
commit + 4ee543e58c5e6cf5ef0b94dfec752dadbbd063d3
blob - fc7b630b038660c7516bd10c73dc8e6ae4c8a00b
blob + e6cde9e1ab18a0b80bc11c95bdd29f11d9da9732
--- src/cmd/rc/exec.c
+++ src/cmd/rc/exec.c
@@ -1,3 +1,6 @@
+#include <u.h>
+#include <signal.h>
+#include <sys/ioctl.h>
 #include "rc.h"
 #include "getflags.h"
 #include "exec.h"
@@ -220,6 +223,7 @@ void Xappend(void){
 }
 void Xasync(void){
 	int null=open("/dev/null", 0);
+	int tty;
 	int pid;
 	char npid[10];
 	if(null<0){
@@ -232,7 +236,33 @@ void Xasync(void){
 		Xerror("try again");
 		break;
 	case 0:
-		pushredir(ROPEN, null, 0);
+		/*
+		 * I don't know what the right thing to do here is,
+		 * so this is all experimentally determined.
+		 * If we just dup /dev/null onto 0, then running
+		 * ssh foo & will reopen /dev/tty, try to read a password,
+		 * get a signal, and repeat, in a tight loop, forever.
+		 * Arguably this is a bug in ssh (it behaves the same
+		 * way under bash as under rc) but I'm fixing it here 
+		 * anyway.  If we dissociate the process from the tty,
+		 * then it won't be able to open /dev/tty ever again.
+		 * The SIG_IGN on SIGTTOU makes writing the tty
+		 * (via fd 1 or 2, for example) succeed even though 
+		 * our pgrp is not the terminal's controlling pgrp.
+		 */
+		if((tty=open("/dev/tty", OREAD)) >= 0){
+			/*
+			 * Should make reads of tty fail, writes succeed.
+			 */
+			signal(SIGTTIN, SIG_IGN);
+			signal(SIGTTOU, SIG_IGN);
+			ioctl(tty, TIOCNOTTY);
+			close(tty);
+		}
+		if(isatty(0))
+			pushredir(ROPEN, null, 0);
+		else
+			close(null);
 		start(runq->code, runq->pc+1, runq->local);
 		runq->ret=0;
 		break;
blob - e81046d619af2a1a121e2d43c44a659860b46174
blob + 6e4aa92444ec7ac768a70b1e8619770cc86a9546
--- src/cmd/rc/havefork.c
+++ src/cmd/rc/havefork.c
@@ -1,3 +1,5 @@
+#include <u.h>
+#include <signal.h>
 #include "rc.h"
 #include "getflags.h"
 #include "exec.h"
@@ -11,7 +13,9 @@ Xasync(void)
 {
 	int null = open("/dev/null", 0);
 	int pid;
+	int tcpgrp, pgrp;
 	char npid[10];
+
 	if(null<0){
 		Xerror("Can't open /dev/null\n");
 		return;
@@ -22,6 +26,12 @@ Xasync(void)
 		Xerror("try again");
 		break;
 	case 0:
+		/*
+		 * Should make reads of tty fail, writes succeed.
+		 */
+		signal(SIGTTIN, SIG_IGN);
+		signal(SIGTTOU, SIG_IGN);
+
 		pushredir(ROPEN, null, 0);
 		start(runq->code, runq->pc+1, runq->local);
 		runq->ret = 0;
blob - 387fbbb8d94ce186de0a3c203c17b2a52a50d9a6
blob + 33d19f43891e154b1e5f293a3a92344652ce82ff
--- src/cmd/rc/plan9ish.c
+++ src/cmd/rc/plan9ish.c
@@ -403,6 +403,7 @@ notifyf(void *unused0, char *s)
 			}
 			goto Out;
 		}
+	if(strcmp(s, "sys: write on closed pipe") != 0)
 	if(strcmp(s, "sys: child") != 0)
 		pfmt(err, "rc: note: %s\n", s);
 	noted(NDFLT);
blob - 0996eec566e7cdac5f1b881c7d08f563f19344c5
blob + 3e79617d55843ff617bb229c680233f0c7d9999e
--- src/cmd/rc/rc.h
+++ src/cmd/rc/rc.h
@@ -9,6 +9,9 @@
 #ifdef	Plan9
 #include <u.h>
 #include <libc.h>
+#undef NSIG
+#undef SIGINT
+#undef SIGQUIT
 #define	NSIG	32
 #define	SIGINT	2
 #define	SIGQUIT	3