diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2007-09-04 20:43:52 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2007-09-04 20:43:52 +0000 |
commit | e85760e05e90b062a3695f66ba5747dee02c3444 (patch) | |
tree | 54e3ffe432f02e7f9325f1548406011f140b5f26 /Src/exec.c | |
parent | 40e70b0419dc570770fb005f1c5c087f24d90182 (diff) | |
download | zsh-e85760e05e90b062a3695f66ba5747dee02c3444.tar.gz zsh-e85760e05e90b062a3695f66ba5747dee02c3444.tar.xz zsh-e85760e05e90b062a3695f66ba5747dee02c3444.zip |
users/11807: fix some job display bugs
Diffstat (limited to 'Src/exec.c')
-rw-r--r-- | Src/exec.c | 218 |
1 files changed, 125 insertions, 93 deletions
diff --git a/Src/exec.c b/Src/exec.c index 6d45f7452..cf79ea88b 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -804,6 +804,105 @@ hashcmd(char *arg0, char **pp) return cn; } +/**/ +int +forklevel; + +/* Arguments to entersubsh() */ +enum { + /* Subshell is to be run asynchronously (else synchronously) */ + ESUB_ASYNC = 0x01, + /* + * Perform process group and tty handling and clear the + * (real) job table, since it won't be any longer valid + */ + ESUB_PGRP = 0x02, + /* Don't unset traps */ + ESUB_KEEPTRAP = 0x04, + /* This is only a fake entry to a subshell */ + ESUB_FAKE = 0x08, + /* Release the process group if pid is the shell's process group */ + ESUB_REVERTPGRP = 0x10, + /* Don't handle the MONITOR option even if previously set */ + ESUB_NOMONITOR = 0x20 +}; + +/**/ +static void +entersubsh(int flags) +{ + int sig, monitor; + + if (!(flags & ESUB_KEEPTRAP)) + for (sig = 0; sig < VSIGCOUNT; sig++) + if (!(sigtrapped[sig] & ZSIG_FUNC)) + unsettrap(sig); + monitor = isset(MONITOR); + if (flags & ESUB_NOMONITOR) + opts[MONITOR] = 0; + if (!isset(MONITOR)) { + if (flags & ESUB_ASYNC) { + settrap(SIGINT, NULL, 0); + settrap(SIGQUIT, NULL, 0); + if (isatty(0)) { + close(0); + if (open("/dev/null", O_RDWR | O_NOCTTY)) { + zerr("can't open /dev/null: %e", errno); + _exit(1); + } + } + } + } else if (thisjob != -1 && (flags & ESUB_PGRP)) { + if (jobtab[list_pipe_job].gleader && (list_pipe || list_pipe_child)) { + if (setpgrp(0L, jobtab[list_pipe_job].gleader) == -1 || + killpg(jobtab[list_pipe_job].gleader, 0) == -1) { + jobtab[list_pipe_job].gleader = + jobtab[thisjob].gleader = (list_pipe_child ? mypgrp : getpid()); + setpgrp(0L, jobtab[list_pipe_job].gleader); + if (!(flags & ESUB_ASYNC)) + attachtty(jobtab[thisjob].gleader); + } + } + else if (!jobtab[thisjob].gleader || + setpgrp(0L, jobtab[thisjob].gleader) == -1) { + jobtab[thisjob].gleader = getpid(); + if (list_pipe_job != thisjob && + !jobtab[list_pipe_job].gleader) + jobtab[list_pipe_job].gleader = jobtab[thisjob].gleader; + setpgrp(0L, jobtab[thisjob].gleader); + if (!(flags & ESUB_ASYNC)) + attachtty(jobtab[thisjob].gleader); + } + } + if (!(flags & ESUB_FAKE)) + subsh = 1; + if ((flags & ESUB_REVERTPGRP) && getpid() == mypgrp) + release_pgrp(); + if (SHTTY != -1) { + shout = NULL; + zclose(SHTTY); + SHTTY = -1; + } + if (isset(MONITOR)) { + signal_default(SIGTTOU); + signal_default(SIGTTIN); + signal_default(SIGTSTP); + } + if (interact) { + signal_default(SIGTERM); + if (!(sigtrapped[SIGINT] & ZSIG_IGNORED)) + signal_default(SIGINT); + } + if (!(sigtrapped[SIGQUIT] & ZSIG_IGNORED)) + signal_default(SIGQUIT); + opts[MONITOR] = opts[USEZLE] = 0; + zleactive = 0; + if (flags & ESUB_PGRP) + clearjobtab(monitor); + get_usage(); + forklevel = locallevel; +} + /* execute a string */ /**/ @@ -1301,7 +1400,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) } else { close(synch[0]); - entersubsh(Z_ASYNC, 0, 0, 0); + entersubsh(ESUB_ASYNC); if (jobtab[list_pipe_job].procs) { if (setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader) == -1) { @@ -1413,7 +1512,8 @@ execpline2(Estate state, wordcode pcode, } else { zclose(pipes[0]); close(synch[0]); - entersubsh(how, 2, 0, 0); + entersubsh(((how & Z_ASYNC) ? ESUB_ASYNC : 0) + | ESUB_PGRP | ESUB_KEEPTRAP); close(synch[1]); execcmd(state, input, pipes[1], how, 0); _exit(lastval); @@ -2419,7 +2519,7 @@ execcmd(Estate state, int input, int output, int how, int last1) (!is_cursh && (last1 != 1 || nsigtrapped || havefiles()))))) { pid_t pid; - int synch[2]; + int synch[2], flags; char dummy; struct timeval bgtime; @@ -2432,7 +2532,9 @@ execcmd(Estate state, int input, int output, int how, int last1) if (oautocont >= 0) opts[AUTOCONTINUE] = oautocont; return; - } if (pid) { + } + if (pid) { + close(synch[1]); read(synch[0], &dummy, 1); close(synch[0]); @@ -2462,7 +2564,10 @@ execcmd(Estate state, int input, int output, int how, int last1) } /* pid == 0 */ close(synch[0]); - entersubsh(how, (type != WC_SUBSH) && !(how & Z_ASYNC) ? 2 : 1, 0, 0); + flags = ((how & Z_ASYNC) ? ESUB_ASYNC : 0) | ESUB_PGRP; + if ((type != WC_SUBSH) && !(how & Z_ASYNC)) + flags |= ESUB_KEEPTRAP; + entersubsh(flags); close(synch[1]); forked = 1; if (sigtrapped[SIGINT] & ZSIG_IGNORED) @@ -2737,10 +2842,16 @@ execcmd(Estate state, int input, int output, int how, int last1) * the current shell (including a fake exec to run a builtin then * exit) in case there is an error return. */ - if (is_exec) - entersubsh(how, (type != WC_SUBSH) ? 2 : 1, 1, - (do_exec || (type >= WC_CURSH && last1 == 1)) - && !forked); + if (is_exec) { + int flags = ((how & Z_ASYNC) ? ESUB_ASYNC : 0) | + ESUB_PGRP | ESUB_FAKE; + if (type != WC_SUBSH) + flags |= ESUB_KEEPTRAP; + if ((do_exec || (type >= WC_CURSH && last1 == 1)) + && !forked) + flags |= ESUB_REVERTPGRP; + entersubsh(flags); + } if (type >= WC_CURSH) { if (last1 == 1) do_exec = 1; @@ -3037,83 +3148,6 @@ fixfds(int *save) errno = old_errno; } -/**/ -int -forklevel; - -/**/ -static void -entersubsh(int how, int cl, int fake, int revertpgrp) -{ - int sig, monitor; - - if (cl != 2) - for (sig = 0; sig < VSIGCOUNT; sig++) - if (!(sigtrapped[sig] & ZSIG_FUNC)) - unsettrap(sig); - if (!(monitor = isset(MONITOR))) { - if (how & Z_ASYNC) { - settrap(SIGINT, NULL, 0); - settrap(SIGQUIT, NULL, 0); - if (isatty(0)) { - close(0); - if (open("/dev/null", O_RDWR | O_NOCTTY)) { - zerr("can't open /dev/null: %e", errno); - _exit(1); - } - } - } - } else if (thisjob != -1 && cl) { - if (jobtab[list_pipe_job].gleader && (list_pipe || list_pipe_child)) { - if (setpgrp(0L, jobtab[list_pipe_job].gleader) == -1 || - killpg(jobtab[list_pipe_job].gleader, 0) == -1) { - jobtab[list_pipe_job].gleader = - jobtab[thisjob].gleader = (list_pipe_child ? mypgrp : getpid()); - setpgrp(0L, jobtab[list_pipe_job].gleader); - if (how & Z_SYNC) - attachtty(jobtab[thisjob].gleader); - } - } - else if (!jobtab[thisjob].gleader || - setpgrp(0L, jobtab[thisjob].gleader) == -1) { - jobtab[thisjob].gleader = getpid(); - if (list_pipe_job != thisjob && - !jobtab[list_pipe_job].gleader) - jobtab[list_pipe_job].gleader = jobtab[thisjob].gleader; - setpgrp(0L, jobtab[thisjob].gleader); - if (how & Z_SYNC) - attachtty(jobtab[thisjob].gleader); - } - } - if (!fake) - subsh = 1; - if (revertpgrp && getpid() == mypgrp) - release_pgrp(); - if (SHTTY != -1) { - shout = NULL; - zclose(SHTTY); - SHTTY = -1; - } - if (isset(MONITOR)) { - signal_default(SIGTTOU); - signal_default(SIGTTIN); - signal_default(SIGTSTP); - } - if (interact) { - signal_default(SIGTERM); - if (!(sigtrapped[SIGINT] & ZSIG_IGNORED)) - signal_default(SIGINT); - } - if (!(sigtrapped[SIGQUIT] & ZSIG_IGNORED)) - signal_default(SIGQUIT); - opts[MONITOR] = opts[USEZLE] = 0; - zleactive = 0; - if (cl) - clearjobtab(monitor); - get_usage(); - forklevel = locallevel; -} - /* * Close internal shell fds. * @@ -3307,8 +3341,7 @@ getoutput(char *cmd, int qt) child_unblock(); zclose(pipes[0]); redup(pipes[1], 1); - opts[MONITOR] = 0; - entersubsh(Z_SYNC, 1, 0, 0); + entersubsh(ESUB_PGRP|ESUB_NOMONITOR); cmdpush(CS_CMDSUBST); execode(prog, 0, 1); cmdpop(); @@ -3460,8 +3493,7 @@ getoutputfile(char *cmd) /* pid == 0 */ redup(fd, 1); - opts[MONITOR] = 0; - entersubsh(Z_SYNC, 1, 0, 0); + entersubsh(ESUB_PGRP|ESUB_NOMONITOR); cmdpush(CS_CMDSUBST); execode(prog, 0, 1); cmdpop(); @@ -3532,7 +3564,7 @@ getproc(char *cmd) zerr("can't open %s: %e", pnam, errno); _exit(1); } - entersubsh(Z_ASYNC, 1, 0, 0); + entersubsh(ESUB_ASYNC|ESUB_PGRP); redup(fd, out); #else /* PATH_DEV_FD */ int pipes[2]; @@ -3558,7 +3590,7 @@ getproc(char *cmd) } return pnam; } - entersubsh(Z_ASYNC, 1, 0, 0); + entersubsh(ESUB_ASYNC|ESUB_PGRP); redup(pipes[out], out); closem(FDT_UNUSED); /* this closes pipes[!out] as well */ #endif /* PATH_DEV_FD */ @@ -3602,7 +3634,7 @@ getpipe(char *cmd, int nullexec) addproc(pid, NULL, 1, &bgtime); return pipes[!out]; } - entersubsh(Z_ASYNC, 1, 0, 0); + entersubsh(ESUB_ASYNC|ESUB_PGRP); redup(pipes[out], out); closem(FDT_UNUSED); /* this closes pipes[!out] as well */ cmdpush(CS_CMDSUBST); |