diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/exec.c | 26 | ||||
-rw-r--r-- | Src/jobs.c | 103 | ||||
-rw-r--r-- | Src/options.c | 1 | ||||
-rw-r--r-- | Src/signals.c | 1 | ||||
-rw-r--r-- | Src/zsh.h | 2 |
5 files changed, 87 insertions, 46 deletions
diff --git a/Src/exec.c b/Src/exec.c index 4f15ebefa..852d75bb5 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -151,6 +151,15 @@ pid_t cmdoutpid; /**/ int cmdoutval; +/* + * This is set by an exiting $(...) substitution to indicate we need + * to retain the status. We initialize it to zero if we think we need + * to reset the status for a command. + */ + +/**/ +int use_cmdoutval; + /* The context in which a shell function is called, see SFC_* in zsh.h. */ /**/ @@ -2262,6 +2271,14 @@ execcmd(Estate state, int input, int output, int how, int last1) */ if (!args && varspc) lastval = errflag ? errflag : cmdoutval; + /* + * If there are arguments, we should reset the status for the + * command before execution---unless we are using the result of a + * command substitution, which will be indicated by setting + * use_cmdoutval to 1. We haven't kicked those off yet, so + * there's no race. + */ + use_cmdoutval = !args; for (i = 0; i < 10; i++) { save[i] = -2; @@ -2478,7 +2495,12 @@ execcmd(Estate state, int input, int output, int how, int last1) lastval = 0; return; } else { - cmdoutval = lastval; + /* + * No arguments. Reset the status if there were + * arguments before and no command substitution + * has provided a status. + */ + cmdoutval = use_cmdoutval ? lastval : 0; if (varspc) addvars(state, varspc, 0); if (errflag) @@ -4674,6 +4696,7 @@ execsave(void) es->badcshglob = badcshglob; es->cmdoutpid = cmdoutpid; es->cmdoutval = cmdoutval; + es->use_cmdoutval = use_cmdoutval; es->trap_return = trap_return; es->trap_state = trap_state; es->trapisfunc = trapisfunc; @@ -4704,6 +4727,7 @@ execrestore(void) badcshglob = exstack->badcshglob; cmdoutpid = exstack->cmdoutpid; cmdoutval = exstack->cmdoutval; + use_cmdoutval = exstack->use_cmdoutval; trap_return = exstack->trap_return; trap_state = exstack->trap_state; trapisfunc = exstack->trapisfunc; diff --git a/Src/jobs.c b/Src/jobs.c index 0841a45c9..6c673b74a 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -813,6 +813,7 @@ should_report_time(Job j) * synch = 0 means asynchronous * synch = 1 means synchronous * synch = 2 means called synchronously from jobs + * synch = 3 means called synchronously from bg or fg * * Returns 1 if some output was done. * @@ -884,12 +885,18 @@ printjob(Job jn, int lng, int synch) } } -/* print if necessary: ignore option state on explicit call to `jobs'. */ - + /* + * - Always print if called from jobs + * - Otherwise, require MONITOR option ("jobbing") and some + * change of state + * - also either the shell is interactive or this is synchronous. + */ if (synch == 2 || - (interact && jobbing && + ((interact || synch) && jobbing && ((jn->stat & STAT_STOPPED) || sflag || job != thisjob))) { int len2, fline = 1; + /* POSIX requires just the job text for bg and fg */ + int plainfmt = (synch == 3) && isset(POSIXJOBS); /* use special format for current job, except in `jobs' */ int thisfmt = job == thisjob && synch != 2; Process qn; @@ -908,54 +915,60 @@ printjob(Job jn, int lng, int synch) for (qn = pn->next; qn; qn = qn->next) { if (qn->status != pn->status) break; - if ((int)strlen(qn->text) + len2 + ((qn->next) ? 3 : 0) > lineleng) + if ((int)strlen(qn->text) + len2 + ((qn->next) ? 3 : 0) + > lineleng) break; len2 += strlen(qn->text) + 2; } doneprint = 1; - if (!thisfmt || lng) { - if (fline) - fprintf(fout, "[%ld] %c ", - (long)job, - (job == curjob) ? '+' - : (job == prevjob) ? '-' : ' '); - else - fprintf(fout, (job > 9) ? " " : " "); - } else - fprintf(fout, "zsh: "); - if (lng & 1) - fprintf(fout, "%ld ", (long) pn->pid); - else if (lng & 2) { - pid_t x = jn->gleader; - - fprintf(fout, "%ld ", (long) x); - do + if (!plainfmt) { + if (!thisfmt || lng) { + if (fline) + fprintf(fout, "[%ld] %c ", + (long)job, + (job == curjob) ? '+' + : (job == prevjob) ? '-' : ' '); + else + fprintf(fout, (job > 9) ? " " : " "); + } else + fprintf(fout, "zsh: "); + if (lng & 1) + fprintf(fout, "%ld ", (long) pn->pid); + else if (lng & 2) { + pid_t x = jn->gleader; + + fprintf(fout, "%ld ", (long) x); + do + skip++; + while ((x /= 10)); skip++; - while ((x /= 10)); - skip++; - lng &= ~3; - } else - fprintf(fout, "%*s", skip, ""); - if (pn->status == SP_RUNNING) { - if (!conted) - fprintf(fout, "running%*s", len - 7 + 2, ""); + lng &= ~3; + } else + fprintf(fout, "%*s", skip, ""); + if (pn->status == SP_RUNNING) { + if (!conted) + fprintf(fout, "running%*s", len - 7 + 2, ""); + else + fprintf(fout, "continued%*s", len - 9 + 2, ""); + } + else if (WIFEXITED(pn->status)) { + if (WEXITSTATUS(pn->status)) + fprintf(fout, "exit %-4d%*s", WEXITSTATUS(pn->status), + len - 9 + 2, ""); + else + fprintf(fout, "done%*s", len - 4 + 2, ""); + } else if (WIFSTOPPED(pn->status)) + fprintf(fout, "%-*s", len + 2, + sigmsg(WSTOPSIG(pn->status))); + else if (WCOREDUMP(pn->status)) + fprintf(fout, "%s (core dumped)%*s", + sigmsg(WTERMSIG(pn->status)), + (int)(len - 14 + 2 - + strlen(sigmsg(WTERMSIG(pn->status)))), ""); else - fprintf(fout, "continued%*s", len - 9 + 2, ""); + fprintf(fout, "%-*s", len + 2, + sigmsg(WTERMSIG(pn->status))); } - else if (WIFEXITED(pn->status)) { - if (WEXITSTATUS(pn->status)) - fprintf(fout, "exit %-4d%*s", WEXITSTATUS(pn->status), - len - 9 + 2, ""); - else - fprintf(fout, "done%*s", len - 4 + 2, ""); - } else if (WIFSTOPPED(pn->status)) - fprintf(fout, "%-*s", len + 2, sigmsg(WSTOPSIG(pn->status))); - else if (WCOREDUMP(pn->status)) - fprintf(fout, "%s (core dumped)%*s", - sigmsg(WTERMSIG(pn->status)), - (int)(len - 14 + 2 - strlen(sigmsg(WTERMSIG(pn->status)))), ""); - else - fprintf(fout, "%-*s", len + 2, sigmsg(WTERMSIG(pn->status))); for (; pn != qn; pn = pn->next) { char *txt = dupstring(pn->text); int txtlen; @@ -1905,7 +1918,7 @@ bin_fg(char *name, char **argv, Options ops, int func) } if (func != BIN_WAIT) /* for bg and fg -- show the job we are operating on */ - printjob(jobtab + job, (stopped) ? -1 : lng, 1); + printjob(jobtab + job, (stopped) ? -1 : lng, 3); if (func != BIN_BG) { /* fg or wait */ if (jobtab[job].pwd && strcmp(jobtab[job].pwd, pwd)) { FILE *fout = (func == BIN_JOBS || !shout) ? stdout : shout; diff --git a/Src/options.c b/Src/options.c index b2b306cd9..8e5308c0b 100644 --- a/Src/options.c +++ b/Src/options.c @@ -201,6 +201,7 @@ static struct optname optns[] = { {{NULL, "posixaliases", OPT_EMULATE|OPT_BOURNE}, POSIXALIASES}, {{NULL, "posixbuiltins", OPT_EMULATE|OPT_BOURNE}, POSIXBUILTINS}, {{NULL, "posixidentifiers", OPT_EMULATE|OPT_BOURNE}, POSIXIDENTIFIERS}, +{{NULL, "posixjobs", OPT_EMULATE|OPT_BOURNE}, POSIXJOBS}, {{NULL, "printeightbit", 0}, PRINTEIGHTBIT}, {{NULL, "printexitvalue", 0}, PRINTEXITVALUE}, {{NULL, "privileged", OPT_SPECIAL}, PRIVILEGED}, diff --git a/Src/signals.c b/Src/signals.c index 5d1797f2f..723b121a8 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -494,6 +494,7 @@ zhandler(int sig) *procsubval = (0200 | WTERMSIG(status)); else *procsubval = WEXITSTATUS(status); + use_cmdoutval = 1; get_usage(); cont = 1; break; diff --git a/Src/zsh.h b/Src/zsh.h index bd872a55a..2a23ad36a 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -930,6 +930,7 @@ struct execstack { int badcshglob; pid_t cmdoutpid; int cmdoutval; + int use_cmdoutval; int trap_return; int trap_state; int trapisfunc; @@ -1955,6 +1956,7 @@ enum { POSIXALIASES, POSIXBUILTINS, POSIXIDENTIFIERS, + POSIXJOBS, PRINTEIGHTBIT, PRINTEXITVALUE, PRIVILEGED, |