ttry harder to put background jobs in background; do not print in response to SIGPIPE - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 4ee543e58c5e6cf5ef0b94dfec752dadbbd063d3
 (DIR) parent ca30274bd90f09b6d19d36b87278fdb40efddada
 (HTM) Author: rsc <devnull@localhost>
       Date:   Fri, 18 Mar 2005 19:03:25 +0000
       
       ttry harder to put background jobs in background; do not print in response to SIGPIPE
       
       Diffstat:
         M src/cmd/rc/exec.c                   |      32 ++++++++++++++++++++++++++++++-
         M src/cmd/rc/havefork.c               |      10 ++++++++++
         M src/cmd/rc/plan9ish.c               |       1 +
         M src/cmd/rc/rc.h                     |       3 +++
       
       4 files changed, 45 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c
       t@@ -1,3 +1,6 @@
       +#include <u.h>
       +#include <signal.h>
       +#include <sys/ioctl.h>
        #include "rc.h"
        #include "getflags.h"
        #include "exec.h"
       t@@ -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){
       t@@ -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;
 (DIR) diff --git a/src/cmd/rc/havefork.c b/src/cmd/rc/havefork.c
       t@@ -1,3 +1,5 @@
       +#include <u.h>
       +#include <signal.h>
        #include "rc.h"
        #include "getflags.h"
        #include "exec.h"
       t@@ -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;
       t@@ -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;
 (DIR) diff --git a/src/cmd/rc/plan9ish.c b/src/cmd/rc/plan9ish.c
       t@@ -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);
 (DIR) diff --git a/src/cmd/rc/rc.h b/src/cmd/rc/rc.h
       t@@ -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