From 084bf17c4bc28a2a651c69fdc9a5bdd6473c3b04 Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Sat, 16 Mar 2019 16:01:57 -0400 Subject: 44132: don't hash commands beginning with / --- Src/exec.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Src/exec.c') diff --git a/Src/exec.c b/Src/exec.c index 042ba065a..79ef83c1e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -940,6 +940,8 @@ hashcmd(char *arg0, char **pp) char *s, buf[PATH_MAX+1]; char **pq; + if (*arg0 == '/') + return NULL; for (; *pp; pp++) if (**pp == '/') { s = buf; -- cgit v1.2.3 From 5c165453ab1d0a91a0b7a5c8493bafddad4eaab2 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Tue, 9 Apr 2019 12:34:04 -0600 Subject: 44214: <(...) substitutions shouldn't grab the terminal --- ChangeLog | 3 +++ Src/exec.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index 82a7ebbf6..801d423a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2019-04-10 Peter Stephenson + * Eric Freese: 44214: Src/exec.c: <(...) substitutions shouldn't + grab the terminal. + * Roman Perepelitsa: 44215: Doc/Zsh/zle.yo, Src/Zle/iwidgets.list, Src/Zle/zle.h, Src/Zle/zle_main.c, Src/Zle/zle_thingy.c, Src/Zle/zle_utils.c, Src/Zle/zle_vi.c: diff --git a/Src/exec.c b/Src/exec.c index 79ef83c1e..6ac852112 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4984,7 +4984,7 @@ getpipe(char *cmd, int nullexec) procsubstpid = pid; return pipes[!out]; } - entersubsh(ESUB_PGRP, NULL); + entersubsh(ESUB_ASYNC|ESUB_PGRP, NULL); redup(pipes[out], out); closem(FDT_UNUSED, 0); /* this closes pipes[!out] as well */ cmdpush(CS_CMDSUBST); -- cgit v1.2.3 From 3de2333b0821a1aaeb3ef98046212b5bf22b596c Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 20 May 2019 00:14:01 +0200 Subject: 44307: allow for atoi() returning a negative number --- ChangeLog | 3 +++ Src/exec.c | 2 +- Src/init.c | 5 ++++- Src/params.c | 6 +++--- Src/utils.c | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index 316c6b484..c67d53356 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2019-05-20 Oliver Kiddle + * 44307: Src/exec.c, Src/init.c, Src/params.c, Src/utils.c: + allow for atoi() returning a negative number + * 44308: Completion/Linux/Command/_modutils: update Linux modutils completion diff --git a/Src/exec.c b/Src/exec.c index 6ac852112..60ab0acf8 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2535,7 +2535,7 @@ setunderscore(char *str) { queue_signals(); if (str && *str) { - int l = strlen(str) + 1, nl = (l + 31) & ~31; + size_t l = strlen(str) + 1, nl = (l + 31) & ~31; if (nl > underscorelen || (underscorelen - nl) > 64) { zfree(zunderscore, underscorelen); diff --git a/Src/init.c b/Src/init.c index 2d5c3296d..445cd3937 100644 --- a/Src/init.c +++ b/Src/init.c @@ -45,7 +45,10 @@ int noexitct = 0; char *zunderscore; /**/ -int underscorelen, underscoreused; +size_t underscorelen; + +/**/ +int underscoreused; /* what level of sourcing we are at */ diff --git a/Src/params.c b/Src/params.c index df031ab64..1859c7c12 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2201,10 +2201,10 @@ getstrvalue(Value v) if (v->flags & VALFLAG_SUBST) { if (v->pm->node.flags & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z)) { - unsigned int fwidth = v->pm->width ? v->pm->width : MB_METASTRLEN(s); + size_t fwidth = v->pm->width ? (unsigned int)v->pm->width : MB_METASTRLEN(s); switch (v->pm->node.flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) { char *t, *tend; - unsigned int t0; + size_t t0; case PM_LEFT: case PM_LEFT | PM_RIGHT_Z: @@ -5858,7 +5858,7 @@ printparamnode(HashNode hn, int printflags) doneminus = 0; } if ((pmptr->flags & PMTF_USE_WIDTH) && p->width) { - printf("%d ", p->width); + printf("%u ", p->width); doneminus = 0; } } diff --git a/Src/utils.c b/Src/utils.c index 32f600858..46cf7bcf6 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3336,7 +3336,7 @@ morefmt: case '.': { long fnsec = nsec; - if (digs > 9) + if (digs < 0 || digs > 9) digs = 9; if (ztrftimebuf(&bufsize, digs)) return -1; -- cgit v1.2.3 From 3bdf4d6641fb34d1c2f130abddb847169a793afe Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 2 Jul 2019 13:42:53 +0100 Subject: 44480: Don't automatically close externally visible file descroptors. These are descriptors marked FDT_EXTERNAL. Make all sysopen'ed file descriptors FDT_EXTERNAL. Make =(...) call closem() consistent with other substitutions. Document file descriptors are left open. --- ChangeLog | 8 ++++++++ Doc/Zsh/mod_socket.yo | 6 ++++-- Doc/Zsh/mod_system.yo | 4 +++- Doc/Zsh/redirect.yo | 3 ++- Src/Modules/system.c | 4 ++-- Src/exec.c | 5 ++++- 6 files changed, 23 insertions(+), 7 deletions(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index 1eb2ef24a..a73915f3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2019-07-02 Peter Stephenson + + * 44480: Doc/Zsh/mod_socket.yo, Doc/Zsh/mod_system.yo, + Doc/Zsh/redirect.yo, Src/Modules/system.c, Src/exec.c: + Don't automatically close FDT_EXTERNAL file descriptors. + All sysopen-created fd's become FDT_EXTERNAL. =(...) + calls closem() consistent with other substitutions. + 2019-07-01 Peter Stephenson * Martijn: 44469: Src/builtin.c, Test/B10getopts.ztst: correct diff --git a/Doc/Zsh/mod_socket.yo b/Doc/Zsh/mod_socket.yo index 867f6081f..78d9254e8 100644 --- a/Doc/Zsh/mod_socket.yo +++ b/Doc/Zsh/mod_socket.yo @@ -43,7 +43,8 @@ startitem() item(tt(zsocket) tt(-l) [ tt(-v) ] [ tt(-d) var(fd) ] var(filename))( tt(zsocket -l) will open a socket listening on var(filename). The shell parameter tt(REPLY) will be set to the file descriptor -associated with that listener. +associated with that listener. The file descriptor remains open in subshells +and forked external executables. If tt(-d) is specified, its argument will be taken as the target file descriptor for @@ -56,7 +57,8 @@ tt(zsocket -a) will accept an incoming connection to the socket associated with var(listenfd). The shell parameter tt(REPLY) will be set to the file descriptor associated with -the inbound connection. +the inbound connection. The file descriptor remains open in subshells +and forked external executables. If tt(-d) is specified, its argument will be taken as the target file descriptor for the diff --git a/Doc/Zsh/mod_system.yo b/Doc/Zsh/mod_system.yo index 3a85e760f..6292af071 100644 --- a/Doc/Zsh/mod_system.yo +++ b/Doc/Zsh/mod_system.yo @@ -45,7 +45,9 @@ specified as a comma-separated list. The following is a list of possible options. Note that, depending on the system, some may not be available. startitem() item(tt(cloexec))( -mark file to be closed when other programs are executed +mark file to be closed when other programs are executed (else +the file descriptor remains open in subshells and forked external +executables) ) xitem(tt(create)) item(tt(creat))( diff --git a/Doc/Zsh/redirect.yo b/Doc/Zsh/redirect.yo index 7e38cd0c3..13496d8d3 100644 --- a/Doc/Zsh/redirect.yo +++ b/Doc/Zsh/redirect.yo @@ -182,7 +182,8 @@ indent(... tt({myfd}>&1)) This opens a new file descriptor that is a duplicate of file descriptor 1 and sets the parameter tt(myfd) to the number of the file descriptor, which will be at least 10. The new file descriptor can be written to using -the syntax tt(>&$myfd). +the syntax tt(>&$myfd). The file descriptor remains open in subshells +and forked external executables. The syntax tt({)var(varid)tt(}>&-), for example tt({myfd}>&-), may be used to close a file descriptor opened in this fashion. Note that the diff --git a/Src/Modules/system.c b/Src/Modules/system.c index 7a4f4ee13..50de59cf9 100644 --- a/Src/Modules/system.c +++ b/Src/Modules/system.c @@ -316,7 +316,7 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func)) int o, fd, moved_fd, explicit = -1; mode_t perms = 0666; #if defined(FD_CLOEXEC) && !defined(O_CLOEXEC) - int fdflags; + int fdflags = 0; #endif if (!OPT_ISSET(ops, 'u')) { @@ -396,8 +396,8 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func)) #endif /* O_CLOEXEC */ fcntl(moved_fd, F_SETFD, FD_CLOEXEC); #endif /* FD_CLOEXEC */ + fdtable[moved_fd] = FDT_EXTERNAL; if (explicit == -1) { - fdtable[moved_fd] = FDT_EXTERNAL; setiparam(fdvar, moved_fd); /* if setting the variable failed, close moved_fd to avoid leak */ if (errflag) diff --git a/Src/exec.c b/Src/exec.c index 60ab0acf8..2acb2c0bc 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4407,8 +4407,10 @@ closem(int how, int all) /* * Process substitution needs to be visible to user; * fd's are explicitly cleaned up by filelist handling. + * External FDs are managed directly by the user. */ - (all || fdtable[i] != FDT_PROC_SUBST) && + (all || (fdtable[i] != FDT_PROC_SUBST && + fdtable[i] != FDT_EXTERNAL)) && (how == FDT_UNUSED || (fdtable[i] & FDT_TYPE_MASK) == how)) { if (i == SHTTY) SHTTY = -1; @@ -4823,6 +4825,7 @@ getoutputfile(char *cmd, char **eptr) } /* pid == 0 */ + closem(FDT_UNUSED, 0); redup(fd, 1); entersubsh(ESUB_PGRP|ESUB_NOMONITOR, NULL); cmdpush(CS_CMDSUBST); -- cgit v1.2.3 From e0d063a2ade821baf570eb300d4be93692b494f8 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sat, 3 Aug 2019 19:48:18 +0100 Subject: 44635: Don't apply STAT_NOPRINT to backgrounded jobs --- ChangeLog | 5 +++++ Src/exec.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index a39ee7665..467b0683e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2019-08-03 Peter Stephenson + + * 44635: Src/exec.c: don't apply STAT_NOPRINT to backgrounded + jobs. + 2019-08-03 Peter Stephenson * 44637: Shlomi Fish: Src/makepro.awk: "=" doesn't need quoting diff --git a/Src/exec.c b/Src/exec.c index 2acb2c0bc..e81053d67 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1690,7 +1690,8 @@ execpline(Estate state, wordcode slcode, int how, int last1) lastwj = thisjob = newjob; - if (list_pipe || (pline_level && !(how & Z_TIMED))) + if (list_pipe || (pline_level && !(how & Z_TIMED) && + !(jn->stat & STAT_NOSTTY))) jn->stat |= STAT_NOPRINT; if (nowait) { -- cgit v1.2.3 From 59901e61cb3e7c8c36bb77c722102e2b9504dc5c Mon Sep 17 00:00:00 2001 From: "_RuRo_ (Андрей Стоцкий)" Date: Wed, 16 Oct 2019 19:26:06 +0300 Subject: 44841: Better checking of errors from "nice" --- ChangeLog | 5 +++++ Src/exec.c | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index c7695c09d..870774090 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2019-10-16 Peter Stephenson + + * _RuRo_ (Андрей Стоцкий): 44841: Src/exec.c: Better error + checking of nice, since return value can be negative. + 2019-10-14 Daniel Shahaf * 44812: Completion/Unix/Command/_subversion: Fix syntax error diff --git a/Src/exec.c b/Src/exec.c index e81053d67..6014ec9a5 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2765,9 +2765,12 @@ execcmd_fork(Estate state, int how, int type, Wordcode varspc, sigtrapped[SIGEXIT] = 0; #ifdef HAVE_NICE /* Check if we should run background jobs at a lower priority. */ - if ((how & Z_ASYNC) && isset(BGNICE)) - if (nice(5) < 0) + if ((how & Z_ASYNC) && isset(BGNICE)) { + errno = 0; + nice(5); + if (errno) zwarn("nice(5) failed: %e", errno); + } #endif /* HAVE_NICE */ return 0; -- cgit v1.2.3 From c578f0a08b9257f3db85dab5431270f1a6eb8858 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Tue, 10 Dec 2019 20:41:08 +0100 Subject: 45004: Fix typos in comments --- ChangeLog | 9 +++++++++ Src/builtin.c | 4 ++-- Src/compat.c | 4 ++-- Src/exec.c | 2 +- Src/glob.c | 4 ++-- Src/hashtable.c | 2 +- Src/hist.c | 4 ++-- Src/init.c | 6 +++--- Src/jobs.c | 2 +- Src/lex.c | 2 +- Src/main.c | 4 ++-- Src/mem.c | 2 +- Src/module.c | 2 +- Src/params.c | 2 +- Src/parse.c | 2 +- Src/pattern.c | 18 +++++++++--------- Src/prompt.c | 2 +- Src/subst.c | 12 ++++++------ Src/text.c | 2 +- Src/watch.c | 2 +- Src/zsh.h | 16 ++++++++-------- Test/A02alias.ztst | 2 +- Test/C01arith.ztst | 2 +- Test/C02cond.ztst | 2 +- Test/D03procsubst.ztst | 2 +- Test/D06subscript.ztst | 4 ++-- Test/D08cmdsubst.ztst | 2 +- Test/E01options.ztst | 2 +- Test/V10private.ztst | 2 +- 29 files changed, 65 insertions(+), 56 deletions(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index e9fe1e78a..434318f27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2019-12-11 Martijn Dekker + * 45004: Src/builtin.c, Src/compat.c, Src/exec.c, Src/glob.c, + Src/hashtable.c, Src/hist.c, Src/init.c, Src/jobs.c, + Src/lex.c, Src/main.c, Src/mem.c, Src/module.c, Src/params.c, + Src/parse.c, Src/pattern.c, Src/prompt.c, Src/subst.c, + Src/text.c, Src/watch.c, Src/zsh.h, Test/A02alias.ztst, + Test/C01arith.ztst, Test/C02cond.ztst, Test/D03procsubst.ztst, + Test/D06subscript.ztst, Test/D08cmdsubst.ztst, + Test/E01options.ztst, Test/V10private.ztst: Fix typos in comments + * 45003: Etc/FAQ.yo, Etc/zsh-development-guide, Functions/Prompts/prompt_oliver_setup, Functions/Zle/insert-composed-char, NEWS, README: Fix more diff --git a/Src/builtin.c b/Src/builtin.c index 18daad4fa..bd7736d2c 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1718,7 +1718,7 @@ fcsubs(char **sp, struct asgment *sub) newstr = sub->value.scalar; sub = (Asgment)sub->node.next; oldpos = s; - /* loop over occurences of oldstr in s, replacing them with newstr */ + /* loop over occurrences of oldstr in s, replacing them with newstr */ while ((newpos = (char *)strstr(oldpos, oldstr))) { newmem = (char *) zhalloc(1 + (newpos - s) + strlen(newstr) + strlen(newpos + strlen(oldstr))); @@ -2526,7 +2526,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), * Attempt to assign a scalar value to an array. * This can happen if the array is special. * We'll be lenient and guess what the user meant. - * This is how normal assigment works. + * This is how normal assignment works. */ if (*asg->value.scalar) { /* Array with one value */ diff --git a/Src/compat.c b/Src/compat.c index 02b66a780..8ab335aa1 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -30,8 +30,8 @@ #include "zsh.mdh" #include "compat.pro" -/* Return pointer to first occurence of string t * - * in string s. Return NULL if not present. */ +/* Return pointer to first occurrence of string t * + * in string s. Return NULL if not present. */ /**/ #ifndef HAVE_STRSTR diff --git a/Src/exec.c b/Src/exec.c index 6014ec9a5..9dc91a71e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4299,7 +4299,7 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p) (unset(RESTRICTED) || !(pm->node.flags & PM_RESTRICTED))) { /* * In this case we're just saving parts of - * the parameter in a tempory, so use heap allocation + * the parameter in a temporary, so use heap allocation * and don't bother copying every detail. */ tpm = (Param) hcalloc(sizeof *tpm); diff --git a/Src/glob.c b/Src/glob.c index 92fd64e7c..a367b082b 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -274,7 +274,7 @@ addpath(char *s, int l) } /* stat the filename s appended to pathbuf. l should be true for lstat, * - * false for stat. If st is NULL, the file is only checked for existance. * + * false for stat. If st is NULL, the file is only checked for existence. * * s == "" is treated as s == ".". This is necessary since on most systems * * foo/ can be used to reference a non-directory foo. Returns nonzero if * * the file does not exists. */ @@ -566,7 +566,7 @@ scanner(Complist q, int shortcircuit) continue; errsfound = errssofar; if (pattry(p, fn)) { - /* if this name matchs the pattern... */ + /* if this name matches the pattern... */ if (pbcwdsav == pathbufcwd && strlen(fn) + pathpos - pathbufcwd >= PATH_MAX) { int err; diff --git a/Src/hashtable.c b/Src/hashtable.c index b7baa3142..e210ddeca 100644 --- a/Src/hashtable.c +++ b/Src/hashtable.c @@ -996,7 +996,7 @@ printshfuncnode(HashNode hn, int printflags) * expansion of leading tabs. * expand = 0 is standard: use hard tabs. * expand > 0 uses that many spaces. - * expand < 0 uses no identation. + * expand < 0 uses no indentation. * * Note this function and the following two are called with * interrupts queued, so saving and restoring text_expand_tabs diff --git a/Src/hist.c b/Src/hist.c index e47be8e15..74116e82f 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -181,7 +181,7 @@ mod_export char *chline; * To avoid having to modify this every time we modify chline, * we set it when we push the stack, and unset it when we pop * the appropriate value off the stack. As it's never modified - * on the stack this is the only maintainance we ever do on it. + * on the stack this is the only maintenance we ever do on it. * In return, ZLE has to check both zle_chline and (if that's * NULL) chline to get the current value. */ @@ -476,7 +476,7 @@ herrflush(void) * * Note that this is a side effect --- this is not the usual reason * for testing lex_add_raw which is to add the text to a different - * buffer used when we are actually parsing the command substituion + * buffer used when we are actually parsing the command substitution * (nothing to do with ZLE). Sorry. */ while (inbufct && (!strin || lex_add_raw)) { diff --git a/Src/init.c b/Src/init.c index 445cd3937..2306d7bdf 100644 --- a/Src/init.c +++ b/Src/init.c @@ -137,7 +137,7 @@ loop(int toplevel, int justonce) else stophist = hstop; /* - * Reset all errors, including user interupts. + * Reset all errors, including user interrupts. * This is what allows ^C in an interactive shell * to return us to the command line. */ @@ -203,7 +203,7 @@ loop(int toplevel, int justonce) * that would be inconsistent with the case where * we didn't execute a preexec function. This is * an implementation detail that an interrupting user - * does't care about. + * doesn't care about. */ errflag &= ~ERRFLAG_ERROR; } @@ -362,7 +362,7 @@ static void parseopts_setemulate(char *nam, int flags) * Parse shell options. * * If (flags & PARSEARGS_TOPLEVEL): - * - we are doing shell initilisation + * - we are doing shell initialisation * - nam is the name under which the shell was started * - set up emulation and standard options based on that. * Otherwise: diff --git a/Src/jobs.c b/Src/jobs.c index c06cb9c79..e7438251e 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1085,7 +1085,7 @@ printjob(Job jn, int lng, int synch) { /* * A subjob still has process, which must finish before - * further excution of the superjob, which the user wants to + * further execution of the superjob, which the user wants to * know about. So report the status of the subjob as if it * were the user-visible superjob. */ diff --git a/Src/lex.c b/Src/lex.c index f43bcc7db..1d86da94e 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -2109,7 +2109,7 @@ skipcomm(void) hist_in_word(1); } else { /* - * Set up for nested command subsitution, however + * Set up for nested command substitution, however * we don't actually need the string until we get * back to the top level and recover the lot. * The $() body just appears empty. diff --git a/Src/main.c b/Src/main.c index 30eef5a25..bad698ee7 100644 --- a/Src/main.c +++ b/Src/main.c @@ -34,7 +34,7 @@ * Support for Cygwin binary/text mode filesystems. * Peter A. Castro * - * This deserves some explaination, because it uses Cygwin specific + * This deserves some explanation, because it uses Cygwin specific * runtime functions. * * Cygwin supports the notion of binary or text mode access to files @@ -43,7 +43,7 @@ * and all. If it's on a text mounted filesystem, Cygwin will strip out * the CRs. This presents a problem because zsh code doesn't allow for * CRLF's as line terminators. So, we must force all open files to be - * in text mode reguardless of the underlying filesystem attributes. + * in text mode regardless of the underlying filesystem attributes. * However, we only want to do this for reading, not writing as we still * want to write files in the mode of the filesystem. To do this, * we have two options: augment all {f}open() calls to have O_TEXT added to diff --git a/Src/mem.c b/Src/mem.c index 77e4375f0..5951e57ed 100644 --- a/Src/mem.c +++ b/Src/mem.c @@ -1120,7 +1120,7 @@ struct m_hdr { /* length of memory header, length of first field of memory header and minimal size of a block left free (if we allocate memory and take a block from the free list that is larger than needed, it must have at - least M_MIN extra bytes to be splitted; if it has, the rest is put on + least M_MIN extra bytes to be split; if it has, the rest is put on the free list) */ #define M_HSIZE (sizeof(struct m_hdr)) diff --git a/Src/module.c b/Src/module.c index 33d75ebbd..f41b82f25 100644 --- a/Src/module.c +++ b/Src/module.c @@ -442,7 +442,7 @@ add_autobin(const char *module, const char *bnam, int flags) } /* Remove the builtin added previously by addbuiltin(). Returns * - * zero on succes and -1 if there is no builtin with that name. */ + * zero on success and -1 if there is no builtin with that name. */ /**/ int diff --git a/Src/params.c b/Src/params.c index a253a9d8e..da7a6b4c5 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3548,7 +3548,7 @@ setiparam(char *s, zlong val) /* * Set an integer parameter without forcing creation of an integer type. - * This is useful if the integer is going to be set to a parmaeter which + * This is useful if the integer is going to be set to a parameter which * would usually be scalar but may not exist. */ diff --git a/Src/parse.c b/Src/parse.c index 53709ac00..de1b27967 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1811,7 +1811,7 @@ par_simple(int *cmplx, int nr) for (ptr = str; *ptr; ptr++) { /* * We can't treat this as "simple" if it contains - * expansions that require process subsitution, since then + * expansions that require process substitution, since then * we need process handling. */ if (ptr[1] == Inpar && diff --git a/Src/pattern.c b/Src/pattern.c index 97d488a31..95e5a79a0 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -156,7 +156,7 @@ typedef union upat *Upat; * P_BRANCH, but applies to the immediately preceding branch. The code in * the corresponding branch is followed by a P_EXCSYNC, which simply * acts as a marker that a P_EXCLUDE comes next. The P_EXCLUDE - * has a pointer to char embeded in it, which works + * has a pointer to char embedded in it, which works * like P_WBRANCH: if we get to the P_EXCSYNC, and we already matched * up to the same position, fail. Thus we are forced to backtrack * on closures in the P_BRANCH if the first attempt was excluded. @@ -502,7 +502,7 @@ patcompcharsset(void) } } -/* Called before parsing a set of file matchs to initialize flags */ +/* Called before parsing a set of file matches to initialize flags */ /**/ void @@ -2082,7 +2082,7 @@ patmungestring(char **string, int *stringlen, int *unmetalenin) } /* - * Allocate memeory for pattern match. Note this is specific to use + * Allocate memory for pattern match. Note this is specific to use * of pattern *and* trial string. * * Unmetafy a trial string for use in pattern matching, if needed. @@ -2103,7 +2103,7 @@ patmungestring(char **string, int *stringlen, int *unmetalenin) * In patstralloc (supplied by caller, must last until last pattry is done) * unmetalen is the unmetafied length of the string; it will be * calculated if the input value is negative. - * unmetalenp is the umetafied length of a path segment preceeding + * unmetalenp is the umetafied length of a path segment preceding * the trial string needed for file mananagement; it is calculated as * needed so does not need to be initialised. * alloced is the memory allocated on the heap --- same as return value from @@ -2237,7 +2237,7 @@ pattrylen(Patprog prog, char *string, int len, int unmetalen, * depends on both prog *and* the trial string). This should only be * done if there is no path prefix (pathpos == 0) as otherwise the path * buffer and unmetafied string may not match. To do this, - * patallocstr() is callled (use force = 1 to ensure it is alway + * patallocstr() is called (use force = 1 to ensure it is always * unmetafied); paststralloc points to existing storage. Memory is * on the heap. * @@ -2331,7 +2331,7 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin, if (patstralloc->alloced) { /* - * Unmetafied; we need pattern sring that's also unmetafied. + * Unmetafied; we need pattern string that's also unmetafied. * We'll cache it in the patstralloc structure. * Note it's on the heap. */ @@ -2389,7 +2389,7 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin, /* * Remember the length in case used for ${..#..} etc. * In this case, we didn't unmetafy the pattern string - * In the orignal structure, but it might be unmetafied + * in the original structure, but it might be unmetafied * for use with an unmetafied test string. */ patinlen = pstrlen; @@ -2619,10 +2619,10 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin, } /* - * Return length of previous succesful match. This is + * Return length of previous successful match. This is * in metafied bytes, i.e. includes a count of Meta characters, * unless the match was done on an unmetafied string using - * a patstralloc stuct, in which case it, too is unmetafed. + * a patstralloc struct, in which case it too is unmetafied. * Unusual and futile attempt at modular encapsulation. */ diff --git a/Src/prompt.c b/Src/prompt.c index 7f4d7a70e..b65bfb86b 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -163,7 +163,7 @@ promptpath(char *p, int npath, int tilde) * * txtchangep gives an integer controlling the attributes of * the prompt. This is for use in zle to maintain the attributes - * consistenly. Other parts of the shell should not need to use it. + * consistently. Other parts of the shell should not need to use it. */ /**/ diff --git a/Src/subst.c b/Src/subst.c index b132f251b..f887dbd24 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -91,7 +91,7 @@ keyvalpairelement(LinkList list, LinkNode node) * "flag"s contains PREFORK_* flags, defined in zsh.h. * * "ret_flags" is used to return PREFORK_* values from nested parameter - * substitions. It may be NULL in which case PREFORK_SUBEXP must not + * substitutions. It may be NULL in which case PREFORK_SUBEXP must not * appear in flags; any return value from below will be discarded. */ @@ -1548,7 +1548,7 @@ untok_and_escape(char *s, int escapes, int tok_arg) /* * See if an argument str looks like a subscript or length following * a colon and parse it. It must be followed by a ':' or nothing. - * If this succeeds, expand and return the evaulated expression if + * If this succeeds, expand and return the evaluated expression if * found, else return NULL. * * We assume this is what is meant if the first character is not @@ -1682,7 +1682,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, */ int wantt = 0; /* - * Indicates spliting a string into an array. There aren't + * Indicates splitting a string into an array. There aren't * actually that many special cases for this --- which may * be why it doesn't work properly; we split in some cases * where we shouldn't, in particular on the multsubs for @@ -1732,7 +1732,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, int mods = 0; /* * The (z) flag, nothing to do with SH_WORD_SPLIT which is tied - * spbreak, see above; fairly straighforward in use but c.f. + * spbreak, see above; fairly straightforward in use but cf. * the comment for mods. * * This gets set to one of the LEXFLAGS_* values. @@ -2725,7 +2725,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * substitution is in quotes) always good enough? Potentially * we may be OK by now --- all potential `@'s and subexpressions * have been handled, including any [@] index which comes up - * by virture of v->isarr being set to SCANPM_ISVAR_AT which + * by virtue of v->isarr being set to SCANPM_ISVAR_AT which * is now in isarr. * * However, if we are replacing multsub() with something that @@ -3110,7 +3110,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, /* * Either loop over an array doing replacements or - * do the replacment on a string. + * do the replacement on a string. * * We need an untokenized value for matching. */ diff --git a/Src/text.c b/Src/text.c index a4191bf1a..69530ae79 100644 --- a/Src/text.c +++ b/Src/text.c @@ -584,7 +584,7 @@ gettext2(Estate state) state->pc = end; if (!nargs) { /* - * Unnamed fucntion. + * Unnamed function. * We're not going to pull any arguments off * later, so skip them now... */ diff --git a/Src/watch.c b/Src/watch.c index cd7dc643d..93b3cb134 100644 --- a/Src/watch.c +++ b/Src/watch.c @@ -98,7 +98,7 @@ /* * In utmpx, the ut_name field is replaced by ut_user. - * Howver, on some systems ut_name may already be defined this + * However, on some systems ut_name may already be defined this * way for the purposes of utmp. */ # ifndef ut_name diff --git a/Src/zsh.h b/Src/zsh.h index fc3ed2127..9194ea82c 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -455,7 +455,7 @@ enum { */ #define FDT_FLOCK_EXEC 6 /* - * Entry used by a process substition. + * Entry used by a process substitution. * This marker is not tested internally as we associated the file * descriptor with a job for closing. * @@ -1255,7 +1255,7 @@ enum { /* * Assignment has value? * If the assignment is an arrray, then it certainly has a value --- we - * can only tell if there's an expicit assignment. + * can only tell if there's an explicit assignment. */ #define ASG_VALUEP(asg) (ASG_ARRAYP(asg) || \ @@ -1444,8 +1444,8 @@ struct builtin { */ #define BINF_HANDLES_OPTS (1<<18) /* - * Handles the assignement interface. The argv list actually contains - * two nested litsts, the first of normal arguments, and the second of + * Handles the assignment interface. The argv list actually contains + * two nested lists, the first of normal arguments, and the second of * assignment structures. */ #define BINF_ASSIGN (1<<19) @@ -2006,7 +2006,7 @@ enum { enum { /* * Set if the string had whitespace at the start - * that should cause word splitting against any preceeding string. + * that should cause word splitting against any preceding string. */ MULTSUB_WS_AT_START = 1, /* @@ -2272,9 +2272,9 @@ struct histent { */ #define LEXFLAGS_NEWLINE 0x0010 -/******************************************/ -/* Definitions for programable completion */ -/******************************************/ +/*******************************************/ +/* Definitions for programmable completion */ +/*******************************************/ /* Nothing special. */ #define IN_NOTHING 0 diff --git a/Test/A02alias.ztst b/Test/A02alias.ztst index 99f7aae26..ca415fa39 100644 --- a/Test/A02alias.ztst +++ b/Test/A02alias.ztst @@ -129,7 +129,7 @@ setopt ALIAS_FUNC_DEF eval 'goodalias() { print does now work; }' isafunc) -0:ALIAS_FUNC_DEF causes the icky behaviour to be avaliable +0:ALIAS_FUNC_DEF causes the icky behaviour to be available >does now work (alias thisisokthough='thisworks() { print That worked; }' diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst index 9dfc065c8..419f45292 100644 --- a/Test/C01arith.ztst +++ b/Test/C01arith.ztst @@ -386,7 +386,7 @@ esac) print after case in subshell) ' -0:Non-arithmetic subst with command subsitution parse from hell +0:Non-arithmetic subst with command substitution parse from hell >yes, this one after case in subshell print "a$((echo one subst) diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 4ffb07dd4..4b1ec02f0 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -388,7 +388,7 @@ F:Failures in these cases do not indicate a problem in the shell. eval test $w print $? done -0:test compatability weirdness: treat ! as a string sometimes +0:test compatibility weirdness: treat ! as a string sometimes >0 >0 >1 diff --git a/Test/D03procsubst.ztst b/Test/D03procsubst.ztst index 1ef55821b..8cf4e2a7f 100644 --- a/Test/D03procsubst.ztst +++ b/Test/D03procsubst.ztst @@ -26,7 +26,7 @@ >SEcond ViErtE diff =(cat FILE1) =(cat FILE2) -1:=(...) substituion +1:=(...) substitution >1c1 >< First Second Third Fourth >--- diff --git a/Test/D06subscript.ztst b/Test/D06subscript.ztst index 3ea7fb7e4..c1a8d79cf 100644 --- a/Test/D06subscript.ztst +++ b/Test/D06subscript.ztst @@ -190,7 +190,7 @@ typeset -ga empty echo X${${empty##*}[-1]}X -0:Negative index applied to substition result from empty array +0:Negative index applied to substitution result from empty array >XX print $empty[(i)] $empty[(I)] @@ -221,7 +221,7 @@ >fimble two three four print X$array[(R)notfound]X -0:(R) yuckily returns the first element on failure withe KSH_ZERO_SUBSCRIPT +0:(R) yuckily returns the first element on failure with KSH_ZERO_SUBSCRIPT >XfimbleX unsetopt KSH_ZERO_SUBSCRIPT diff --git a/Test/D08cmdsubst.ztst b/Test/D08cmdsubst.ztst index 4e0759e35..04bf698aa 100644 --- a/Test/D08cmdsubst.ztst +++ b/Test/D08cmdsubst.ztst @@ -174,6 +174,6 @@ eval '{ OPEN print hi; CLOSE } var=$({ OPEN print bye; CLOSE}) && print $var' ) -0:Alias expansion needed in parsing substituions +0:Alias expansion needed in parsing substitutions >hi >bye diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 0f6bb3455..c4b101bdb 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -850,7 +850,7 @@ # With non-special command: original value restored # With special builtin: new value kept - # With special builtin preceeded by "command": original value restored. + # With special builtin preceded by "command": original value restored. (setopt posixbuiltins FOO=val0 FOO=val1 true; echo $FOO diff --git a/Test/V10private.ztst b/Test/V10private.ztst index 880784e12..a3a63867b 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -104,7 +104,7 @@ private -h path print X$path } -0:privates may hide tied paramters +0:privates may hide tied parameters >X # Deliberate type mismatch here -- cgit v1.2.3 From 1baf0d1f553631ecb641e98f4bf48bc2a44e5b82 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 15 Dec 2019 19:04:04 +0000 Subject: 45025: fix re-entrancy problem with memory management in readoutput(). This could cause a signal received during $(...) to corrupt memory. --- ChangeLog | 6 ++++++ Src/exec.c | 61 ++++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 25 deletions(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index 3b3b9c65b..d241323b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2019-12-15 Peter Stephenson + + * 45025: Src/exec.c: fix re-entrancy problem with memory + management in readoutput(). This could cause a signal + received during $(...) to corrupt memory. + 2019-12-14 dana * unposted: Config/version.mk, Etc/FAQ.yo, README: Update for diff --git a/Src/exec.c b/Src/exec.c index 9dc91a71e..64eee7dc4 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4646,19 +4646,25 @@ getoutput(char *cmd, int qt) return NULL; } -/* read output of command substitution */ +/* read output of command substitution + * + * The file descriptor "in" is closed by the function. + * + * "qt" indicates if the substitution was in double quotes. + * + * "readerror", if not NULL, is used to return any error that + * occurred during the read. + */ /**/ mod_export LinkList readoutput(int in, int qt, int *readerror) { LinkList ret; - char *buf, *ptr; - int bsiz, c, cnt = 0; - FILE *fin; + char *buf, *bufptr, *ptr, inbuf[64]; + int bsiz, c, cnt = 0, readret; int q = queue_signal_level(); - fin = fdopen(in, "r"); ret = newlinklist(); ptr = buf = (char *) hcalloc(bsiz = 64); /* @@ -4670,33 +4676,38 @@ readoutput(int in, int qt, int *readerror) */ dont_queue_signals(); child_unblock(); - while ((c = fgetc(fin)) != EOF || errno == EINTR) { - if (c == EOF) { - errno = 0; - clearerr(fin); - continue; - } - if (imeta(c)) { - *ptr++ = Meta; - c ^= 32; - cnt++; + for (;;) { + readret = read(in, inbuf, 64); + if (readret <= 0) { + if (readret < 0 && errno == EINTR) + continue; + else + break; } - if (++cnt >= bsiz) { - char *pp; - queue_signals(); - pp = (char *) hcalloc(bsiz *= 2); - dont_queue_signals(); + for (bufptr = inbuf; bufptr < inbuf + readret; bufptr++) { + c = *bufptr; + if (imeta(c)) { + *ptr++ = Meta; + c ^= 32; + cnt++; + } + if (++cnt >= bsiz) { + char *pp; + queue_signals(); + pp = (char *) hcalloc(bsiz *= 2); + dont_queue_signals(); - memcpy(pp, buf, cnt - 1); - ptr = (buf = pp) + cnt - 1; + memcpy(pp, buf, cnt - 1); + ptr = (buf = pp) + cnt - 1; + } + *ptr++ = c; } - *ptr++ = c; } child_block(); restore_queue_signals(q); if (readerror) - *readerror = ferror(fin) ? errno : 0; - fclose(fin); + *readerror = readret < 0 ? errno : 0; + close(in); while (cnt && ptr[-1] == '\n') ptr--, cnt--; *ptr = '\0'; -- cgit v1.2.3 From 8bc4400762289e5cdbcfa50aab5982f8e7e28dfc Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Tue, 17 Dec 2019 04:43:48 +0000 Subject: 45058: internal: Add symbolic names to possible values of zexit()'s "from_where" parameter. No functional change. --- ChangeLog | 5 +++++ Src/Modules/zpty.c | 2 +- Src/Zle/zle_main.c | 4 ++-- Src/builtin.c | 24 +++++++++++++----------- Src/exec.c | 2 +- Src/init.c | 10 +++++----- Src/signals.c | 8 ++++---- Src/subst.c | 2 +- Src/zsh.h | 8 ++++++++ 9 files changed, 40 insertions(+), 25 deletions(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index 4ae35b692..9b7571f8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2019-12-17 Daniel Shahaf + * 45058: Src/Modules/zpty.c, Src/Zle/zle_main.c, Src/builtin.c, + Src/exec.c, Src/init.c, Src/signals.c, Src/subst.c, Src/zsh.h: + internal: Add symbolic names to possible values of zexit()'s + "from_where" parameter. No functional change. + * unposted: Src/builtin.c: Update comment to reflect variable rename in 41012 (zsh-5.3.1-182-gd7110d8f0). diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c index 2f83f7ce6..45fd15ee0 100644 --- a/Src/Modules/zpty.c +++ b/Src/Modules/zpty.c @@ -426,7 +426,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock) execode(prog, 1, 0, "zpty"); stopmsg = 2; mypid = 0; /* trick to ensure we _exit() */ - zexit(lastval, 0); + zexit(lastval, ZEXIT_NORMAL); } master = movefd(master); if (master == -1) { diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 27dc8ef21..22cb21be3 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -905,7 +905,7 @@ getbyte(long do_keytmout, int *timeout, int full) if ((zlereadflags & ZLRF_IGNOREEOF) && icnt++ < 20) continue; stopmsg = 1; - zexit(1, 0); + zexit(1, ZEXIT_NORMAL); } icnt = 0; if (errno == EINTR) { @@ -928,7 +928,7 @@ getbyte(long do_keytmout, int *timeout, int full) } else if (errno != 0) { zerr("error on TTY read: %e", errno); stopmsg = 1; - zexit(1, 0); + zexit(1, ZEXIT_NORMAL); } } if (cc == '\r') /* undo the exchange of \n and \r determined by */ diff --git a/Src/builtin.c b/Src/builtin.c index 00b5d5c50..5fe5ea6d1 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5665,7 +5665,7 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func) } return lastval; } - zexit(num, 0); /* else treat return as logout/exit */ + zexit(num, ZEXIT_NORMAL); /* else treat return as logout/exit */ break; case BIN_LOGOUT: if (unset(LOGINSHELL)) { @@ -5687,7 +5687,7 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func) * If we are already exiting... give this all up as * a bad job. */ - if (stopmsg || (zexit(0,2), !stopmsg)) { + if (stopmsg || (zexit(0, ZEXIT_DEFERRED), !stopmsg)) { retflag = 1; breaks = loops; exit_pending = 1; @@ -5695,7 +5695,7 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func) exit_val = num; } } else - zexit(num, 0); + zexit(num, ZEXIT_NORMAL); break; } return 0; @@ -5780,14 +5780,15 @@ _realexit(void) /* exit the shell. val is the return value of the shell. * * from_where is - * 1 if zexit is called because of a signal - * 2 if we can't actually exit yet (e.g. functions need - * terminating) but should perform the usual interactive tests. + * ZEXIT_SIGNAL if zexit is called because of a signal + * ZEXIT_DEFERRED if we can't actually exit yet (e.g., functions need + * terminating) but should perform the usual interactive + * tests. */ /**/ mod_export void -zexit(int val, int from_where) +zexit(int val, enum zexit_t from_where) { /* * Don't do anything recursively: see below. @@ -5798,7 +5799,7 @@ zexit(int val, int from_where) if (shell_exiting == -1) return; - if (isset(MONITOR) && !stopmsg && from_where != 1) { + if (isset(MONITOR) && !stopmsg && from_where != ZEXIT_SIGNAL) { scanjobs(); /* check if jobs need printing */ if (isset(CHECKJOBS)) checkjobs(); /* check if any jobs are running/stopped */ @@ -5808,7 +5809,8 @@ zexit(int val, int from_where) } } /* Positive shell_exiting means we have been here before */ - if (from_where == 2 || (shell_exiting++ && from_where)) + if (from_where == ZEXIT_DEFERRED || + (shell_exiting++ && from_where != ZEXIT_NORMAL)) return; /* @@ -5824,12 +5826,12 @@ zexit(int val, int from_where) if (isset(MONITOR)) { /* send SIGHUP to any jobs left running */ - killrunjobs(from_where == 1); + killrunjobs(from_where == ZEXIT_SIGNAL); } if (isset(RCS) && interact) { if (!nohistsave) { int writeflags = HFILE_USE_OPTIONS; - if (from_where == 1) + if (from_where == ZEXIT_SIGNAL) writeflags |= HFILE_NO_REWRITE; saveandpophiststack(1, writeflags); savehistfile(NULL, 1, writeflags); diff --git a/Src/exec.c b/Src/exec.c index 64eee7dc4..0d9d7de7c 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5949,7 +5949,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) * exit command was handled. */ stopmsg = 1; - zexit(exit_val, 0); + zexit(exit_val, ZEXIT_NORMAL); } } diff --git a/Src/init.c b/Src/init.c index 2306d7bdf..2e2ef881c 100644 --- a/Src/init.c +++ b/Src/init.c @@ -161,7 +161,7 @@ loop(int toplevel, int justonce) * Handle that now. */ stopmsg = 1; - zexit(exit_val, 0); + zexit(exit_val, ZEXIT_NORMAL); } if (tok == LEXERR && !lastval) lastval = 1; @@ -1371,7 +1371,7 @@ init_misc(char *cmd, char *zsh_name) bshin = fdopen(SHIN, "r"); execstring(cmd, 0, 1, "cmdarg"); stopmsg = 1; - zexit((exit_pending || shell_exiting) ? exit_val : lastval, 0); + zexit((exit_pending || shell_exiting) ? exit_val : lastval, ZEXIT_NORMAL); } if (interact && isset(RCS)) @@ -1778,20 +1778,20 @@ zsh_main(UNUSED(int argc), char **argv) if (!lastval) lastval = 1; stopmsg = 1; - zexit(lastval, 0); + zexit(lastval, ZEXIT_NORMAL); } if (!(isset(IGNOREEOF) && interact)) { #if 0 if (interact) fputs(islogin ? "logout\n" : "exit\n", shout); #endif - zexit(lastval, 0); + zexit(lastval, ZEXIT_NORMAL); continue; } noexitct++; if (noexitct >= 10) { stopmsg = 1; - zexit(lastval, 0); + zexit(lastval, ZEXIT_NORMAL); } /* * Don't print the message if it was already handled by diff --git a/Src/signals.c b/Src/signals.c index 14218177a..96ff9e9b3 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -654,7 +654,7 @@ zhandler(int sig) _exit(SIGPIPE); else if (!isatty(SHTTY)) { stopmsg = 1; - zexit(SIGPIPE, 1); + zexit(SIGPIPE, ZEXIT_SIGNAL); } } break; @@ -662,7 +662,7 @@ zhandler(int sig) case SIGHUP: if (!handletrap(SIGHUP)) { stopmsg = 1; - zexit(SIGHUP, 1); + zexit(SIGHUP, ZEXIT_SIGNAL); } break; @@ -670,7 +670,7 @@ zhandler(int sig) if (!handletrap(SIGINT)) { if ((isset(PRIVILEGED) || isset(RESTRICTED)) && isset(INTERACTIVE) && (noerrexit & NOERREXIT_SIGNAL)) - zexit(SIGINT, 1); + zexit(SIGINT, ZEXIT_SIGNAL); if (list_pipe || chline || simple_pline) { breaks = loops; errflag |= ERRFLAG_INT; @@ -703,7 +703,7 @@ zhandler(int sig) errflag = noerrs = 0; zwarn("timeout"); stopmsg = 1; - zexit(SIGALRM, 1); + zexit(SIGALRM, ZEXIT_SIGNAL); } } break; diff --git a/Src/subst.c b/Src/subst.c index f887dbd24..79efc9ad2 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3044,7 +3044,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * shouldn't be any if not interactive. */ stopmsg = 1; - zexit(1, 0); + zexit(1, ZEXIT_NORMAL); } else _exit(1); } diff --git a/Src/zsh.h b/Src/zsh.h index 9194ea82c..657e6d8ec 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -3222,6 +3222,14 @@ enum { /* Hooks in core. */ /***************************************/ +/* The type of zexit()'s second parameter, which see. */ +enum zexit_t { + /* This isn't a bitfield. The values are here just for explicitness. */ + ZEXIT_NORMAL = 0, + ZEXIT_SIGNAL = 1, + ZEXIT_DEFERRED = 2 +}; + #define EXITHOOK (zshhooks + 0) #define BEFORETRAPHOOK (zshhooks + 1) #define AFTERTRAPHOOK (zshhooks + 2) -- cgit v1.2.3 From ae7e291873c1f80c51f53db934a87df2c0eaf821 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Tue, 17 Dec 2019 07:44:28 +0000 Subject: 45066: internal: Document forklevel, locallevel, and exit_pending. --- ChangeLog | 3 +++ Src/builtin.c | 6 +++++- Src/exec.c | 4 ++++ Src/params.c | 6 +++++- 4 files changed, 17 insertions(+), 2 deletions(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index 4821b09b6..742ddab9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2019-12-18 Daniel Shahaf + * 45066: Src/builtin.c, Src/exec.c, Src/params.c: internal: + Document forklevel, locallevel, and exit_pending. + * 45065: Src/Makefile.in: Make 'make -s' print nothing when it does nothing. diff --git a/Src/builtin.c b/Src/builtin.c index 5fe5ea6d1..0ecabf854 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5601,7 +5601,11 @@ bin_getopts(UNUSED(char *name), char **argv, UNUSED(Options ops), UNUSED(int fun return 0; } -/* Flag that we should exit the shell as soon as all functions return. */ +/* Boolean flag that we should exit the shell as soon as all functions return. + * + * Set by the 'exit' builtin. + */ + /**/ mod_export int exit_pending; diff --git a/Src/exec.c b/Src/exec.c index 0d9d7de7c..50027654a 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -971,6 +971,10 @@ hashcmd(char *arg0, char **pp) return cn; } +/* The value that 'locallevel' had when we forked. When we get back to this + * level, the current process (which is a subshell) will terminate. + */ + /**/ int forklevel; diff --git a/Src/params.c b/Src/params.c index da7a6b4c5..5eaafe34e 100644 --- a/Src/params.c +++ b/Src/params.c @@ -44,7 +44,11 @@ #endif #endif -/* what level of localness we are at */ +/* What level of localness we are at. + * + * Hand-wavingly, this is incremented at every function call and decremented + * at every function return. See startparamscope(). + */ /**/ mod_export int locallevel; -- cgit v1.2.3 From fd068221b7fbbcfe89ec74c7eeb0138e90e14b13 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 18 Dec 2019 10:51:59 +0000 Subject: 45083: Add signal protection to execarith(). Otherwise we could get re-entrancy in memory functions when setting variables. --- ChangeLog | 5 +++++ Src/exec.c | 3 +++ 2 files changed, 8 insertions(+) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index cc0ad1d8e..897114d3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2019-12-18 Peter Stephenson + + * 45083: Src/exec.c: execarith() needs signal protection as + it sets variables. + 2019-12-18 Daniel Shahaf * 45076: Src/loop.c: internal: Simplify handling of diff --git a/Src/exec.c b/Src/exec.c index 50027654a..fac095d64 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5101,6 +5101,7 @@ execarith(Estate state, UNUSED(int do_exec)) mnumber val = zero_mnumber; int htok = 0; + queue_signals(); if (isset(XTRACE)) { printprompt4(); fprintf(xtrerr, "(("); @@ -5120,6 +5121,8 @@ execarith(Estate state, UNUSED(int do_exec)) fprintf(xtrerr, " ))\n"); fflush(xtrerr); } + unqueue_signals(); + if (errflag) { errflag &= ~ERRFLAG_ERROR; return 2; -- cgit v1.2.3 From 581585dfc66e2bb18434cdd1ad2f5899b12a86dd Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sun, 26 Jan 2020 01:17:00 +0000 Subject: 45343: Queue signals around arithmetic evaluations The queueing added in execarith() in 45083 is reverted since the callee does this now. --- ChangeLog | 3 +++ Src/exec.c | 3 --- Src/math.c | 15 +++++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'Src/exec.c') diff --git a/ChangeLog b/ChangeLog index f15cfbe56..95a94db07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2020-01-29 Daniel Shahaf + * 45343: Src/exec.c, Src/math.c: Queue signals around arithmetic + evaluations + * 45344: INSTALL: Document where third-party completion functions should be installed. diff --git a/Src/exec.c b/Src/exec.c index fac095d64..50027654a 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5101,7 +5101,6 @@ execarith(Estate state, UNUSED(int do_exec)) mnumber val = zero_mnumber; int htok = 0; - queue_signals(); if (isset(XTRACE)) { printprompt4(); fprintf(xtrerr, "(("); @@ -5121,8 +5120,6 @@ execarith(Estate state, UNUSED(int do_exec)) fprintf(xtrerr, " ))\n"); fflush(xtrerr); } - unqueue_signals(); - if (errflag) { errflag &= ~ERRFLAG_ERROR; return 2; diff --git a/Src/math.c b/Src/math.c index a38770073..905b910ec 100644 --- a/Src/math.c +++ b/Src/math.c @@ -1133,8 +1133,7 @@ notzero(mnumber a) /* macro to pop three values off the value stack */ -/**/ -void +static void op(int what) { mnumber a, b, c, *spval; @@ -1569,14 +1568,19 @@ mathparse(int pc) if (errflag) return; + queue_signals(); mtok = zzlex(); /* Handle empty input */ - if (pc == TOPPREC && mtok == EOI) + if (pc == TOPPREC && mtok == EOI) { + unqueue_signals(); return; + } checkunary(mtok, optr); while (prec[mtok] <= pc) { - if (errflag) + if (errflag) { + unqueue_signals(); return; + } switch (mtok) { case NUM: push(yyval, NULL, 0); @@ -1595,6 +1599,7 @@ mathparse(int pc) if (mtok != M_OUTPAR) { if (!errflag) zerr("bad math expression: ')' expected"); + unqueue_signals(); return; } break; @@ -1613,6 +1618,7 @@ mathparse(int pc) if (mtok != COLON) { if (!errflag) zerr("bad math expression: ':' expected"); + unqueue_signals(); return; } if (q) @@ -1636,4 +1642,5 @@ mathparse(int pc) mtok = zzlex(); checkunary(mtok, optr); } + unqueue_signals(); } -- cgit v1.2.3