aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc/exec.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-03-18 19:03:25 +0000
committerrsc <devnull@localhost>2005-03-18 19:03:25 +0000
commit4ee543e58c5e6cf5ef0b94dfec752dadbbd063d3 (patch)
tree2bfb7c9dbe3dcc28e639d734df00cceb33b1be88 /src/cmd/rc/exec.c
parentca30274bd90f09b6d19d36b87278fdb40efddada (diff)
downloadplan9port-4ee543e58c5e6cf5ef0b94dfec752dadbbd063d3.tar.gz
plan9port-4ee543e58c5e6cf5ef0b94dfec752dadbbd063d3.tar.bz2
plan9port-4ee543e58c5e6cf5ef0b94dfec752dadbbd063d3.zip
try harder to put background jobs in background; do not print in response to SIGPIPE
Diffstat (limited to 'src/cmd/rc/exec.c')
-rw-r--r--src/cmd/rc/exec.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c
index fc7b630b..e6cde9e1 100644
--- a/src/cmd/rc/exec.c
+++ b/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;