summaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
5 daysredir: Fix double close in dupredirectHEADmasterHerbert Xu1-3/+1
For a redirection like "> /dev/null" dupredirect will close the newly opened file descriptor twice in a row because sh_dup2 also closes the new file descriptor. Remove the extra close in dupredirect. Fixes: 509f5b0dcd71 ("redir: Use memfd_create instead of pipe") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
5 daysalias: Mark printalias as noinlineHerbert Xu1-2/+1
The function printalias is not any critical path and inlining it makes no sense. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
5 daysmystring: Add a few more uses of snlfmtHerbert Xu3-3/+3
Use snlfmt in a few more places. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
5 daysinput: Fix potential out-of-bounds read in popstringHerbert Xu1-1/+1
For an empty alias, the check on the last character of the alias in popstring may read a bogus byte. Fix this by checking whether the alias is empty or not before reading the last byte. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
5 daysexpand: Fix naked backslah leakageHerbert Xu3-3/+10
Naked backslashes in patterns may incorrectly unquote subsequent wild characters that are themselves quoted. Fix this by adding an extra backslash when necessary. Test case: a="\\*bc"; b="\\"; c="*"; echo "<${a##$b"$c"}>" Old result: <> New result: <bc> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
13 daysalias: Simplify alias storageHarald van Dijk4-44/+42
Rather than storing the alias name and value separately, we can reduce simplify code and reduce code size by storing them in name=value form. This allows us to re-use some code from var.c to handle hashing and comparisons, so long as we update that to account for aliases' special handling of a leading = character. This is okay to do for variables as well, as for variables the leading character is guaranteed to not be =. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
13 daysmain: Fix profiling on longjmp exit pathsHerbert Xu1-1/+2
Ensure that longjmp exit paths also write the profiling file. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
13 daysinput: Fix history line reading regressionHerbert Xu1-1/+2
When a newline is encountered with history support, terminate the loop immediately. Fixes: 44ae22beedf8 ("input: Disable lleft in SMALL mode") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-28redir: Use memfd_create instead of pipeHerbert Xu5-22/+50
Use memfd_create(2) instead of pipe(2). With pipe(2), a fork is required if the amount of data to be written exceeds the pipe size. This is not the case with memfd_create. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-28jobs: Preserve parent jobs for simple commandsHerbert Xu4-2/+18
Do not free parent shell jobs if a simple command with the first word being "jobs" is executed as a command substitution. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-28trap: Preserve parent traps for trap-only command substitutionHerbert Xu5-20/+52
Traps are reset when a subshell is started. When a subshell is started for command substitution with a simple command whose first word is "trap", preserve the parent trap text so that they can be printed. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-28parser: Extend coverage of CHKEOFMARKHerbert Xu3-54/+97
Extend the coverage of CHKEOFMARK to cover parameter expansion, arithmetic expansion, and command substitution. For command substitution, use the reconstruction from commandtext as the here-document marker. Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-21expand: Fix here-document file descriptor leakHerbert Xu1-3/+3
Swap the order of here-document expansion and pipe creation as otherwise the pipe file descriptors will become accessible in the expanded text. Fixes: f4ee8c859c3d ("[EXPAND] Expand here-documents in the...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-21alias: Disallow non-CWORD charactersHerbert Xu1-0/+6
Alias names containing control characters may match words from the parser that shouldn't be matched. Disallow such characters from appearing in an alias name. Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-12var: Remove unused VNOSETHerbert Xu2-6/+1
The bit VNOSET is no longer used. Remove it. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-12var: Fix unexporting of local variables using unsetHerbert Xu1-3/+8
Local variables and other variables with the flag VSTRFIXED set could not be unexported using the unset command. Fix this by adding a special case in setvareq for them. Reported-by: Christoph Anton Mitterer <calestyo@scientia.org> Fixes: e3c9a7dd7097 ("[VAR] Move unsetvar functionality into setvareq") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-12alias: Fix out-of-bound accessHerbert Xu1-1/+2
Check for empty string before searching for equal sign starting at n+1 in aliascmd. Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-12jobs: Allow monitor mode without a tty in non-interactive modeHerbert Xu1-18/+35
When a tty is unavailable, or the shell is in the background, job control could still be used for the purpose of setting process groups. This is based on work by Jilles Tjoelker from FreeBSD and Steffen Nurpmeso. Reported-by: Steffen Nurpmeso <steffen@sdaoden.eu> Reported-by: Ganael Laplanche <ganael.laplanche@martymac.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-12exec: Check executable bit when searching pathHerbert Xu3-24/+29
Andrej Shadura <andrew.shadura@collabora.co.uk> wrote: > > Here's an old bug from 2017, but it was brought to my attention in some > recent discussion about which "which" is which. There's also a patch in > one of the follow-ups, but I'm afraid I don't know enough about that > part of code to judge the consequences of it being applied: > > https://bugs.debian.org/874264 > > -------- Forwarded Message -------- > Subject: dash: 'command -v' mistakenly returns a shell script whose > executable is not set > Date: Mon, 04 Sep 2017 10:45:48 -0400 > From: Norman Ramsey <nr@cs.tufts.edu> > To: Debian Bug Tracking System <submit@bugs.debian.org> > > Package: dash > Version: 0.5.8-2.4 > Severity: normal > > Dear Maintainer, > > > I tracked a build bug in s-nail to a problem with dash. Symptom: > building s-nail tries to run /home/nr/bin/clang, a script whose > executable bit is not set. We tracked the problem to the result of > running `command -v clang` with /bin/sh: > > nr@homedog ~/n/s-nail> /bin/sh -c 'command -v clang' > /home/nr/bin/clang > nr@homedog ~/n/s-nail> ls -l /home/nr/bin/clang > -rw-rw-r-- 1 nr nr 1009 Aug 29 2011 /home/nr/bin/clang > nr@homedog ~/n/s-nail> ls -l /bin/sh > lrwxrwxrwx 1 root root 4 Jan 24 2017 /bin/sh -> dash > nr@homedog ~/n/s-nail> ksh -c 'command -v clang' > /usr/bin/clang > nr@homedog ~/n/s-nail> bash -c 'command -v clang' > /usr/bin/clang > nr@homedog ~/n/s-nail> sh -c 'command -v clang' > /home/nr/bin/clang > nr@homedog ~/n/s-nail> dash -c 'command -v clang' > /home/nr/bin/clang > nr@homedog ~/n/s-nail> fish -c 'command -v clang' > /usr/bin/clang > > When I run `command -v clang` I expect it to answer /usr/bin/clang. > > -- System Information: > Debian Release: 9.1 > APT prefers stable > APT policy: (990, 'stable'), (500, 'stable'), (1, 'experimental') > Architecture: i386 (x86_64) > Foreign Architectures: amd64 > > Kernel: Linux 4.9.0-3-amd64 (SMP w/4 CPU cores) > Locale: LANG=C, LC_CTYPE=C (charmap=UTF-8) (ignored: LC_ALL set to > en_US.utf8), LANGUAGE=C (charmap=UTF-8) (ignored: LC_ALL set to en_US.utf8) > Shell: /bin/sh linked to /bin/dash > Init: systemd (via /run/systemd/system) > > Versions of packages dash depends on: > ii debianutils 4.8.1.1 > ii dpkg 1.18.24 > ii libc6 2.24-11+deb9u1 > > dash recommends no packages. > > dash suggests no packages. > > -- debconf information: > * dash/sh: true This is inherited from NetBSD. There is even a commented-out block of code that tried to fix this. Anyway, we now have faccessat so we can simply use it. Reported-by: Norman Ramsey <nr@cs.tufts.edu> Reported-by: Nicola Lamacchia <nicola.lamacchia@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-07configure.ac: drop -Wl,--fatal-warningsFabrice Fontaine1-1/+1
Drop -Wl,--fatal-warnings with --enable-static to avoid the following static build failure: configure:4778: checking for strtod configure:4778: /home/autobuild/autobuild/instance-8/output-1/host/bin/powerpc-buildroot-linux-uclibcspe-gcc -o conftest -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -mabi=spe -mfloat-gprs=single -Wa,-me500 -Os -g0 -static -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -static -Wl,--fatal-warnings conftest.c >&5 /home/autobuild/autobuild/instance-8/output-1/host/lib/gcc/powerpc-buildroot-linux-uclibcspe/8.4.0/../../../../powerpc-buildroot-linux-uclibcspe/bin/ld: warning: conftest has a LOAD segment with RWX permissions collect2: error: ld returned 1 exit status [...] In file included from arith_yylex.c:44: system.h:74:22: error: static declaration of 'strtod' follows non-static declaration static inline double strtod(const char *nptr, char **endptr) ^~~~~~ Fixes: - http://autobuild.buildroot.org/results/a54fdc7d1b94beb47203373ae35b08d9cea8d42c Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06man: document what happens when IFS= (and when it's not)наб1-0/+13
A question I just got from a user was "how do I make while read -r l; do ...; done < f not strip the initial tabs?". Turns out, the manual is silent on this, and POSIX just about implies this behaviour. (Indeed, our read is almost verbatim POSIX, and both defer to Field Splitting, but our Field Splitting isn't nearly as detailed, and thank god.) Even POSIX spends just one line describing this pivotal behaviour (Issue 8 Draft 2.1 line 75044-75045: "2. If the value of IFS is null, field splitting shall have no effect, except that if the input is empty the result shall be zero fields.)," and when I first encountered this it was also quite surprising to me. Spell it out explicitly: IFS= means that input is preserved, and the default value means whitespace is stripped from the front. Drive it home with an example because it's esoteric (and I know from that user that they first tried searching for read in the manual, but it was not very helpful). Reported-by: rozbrajaczpoziomow <rozbrajaczpoziomow@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06jobs: drop unused node parameter in makejob()Denys Vlasenko3-8/+7
CC: dash@vger.kernel.org CC: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06shell: Prototype all function definitions for C23 compatнаб6-44/+14
With this patch, you're just left with the histedit.c warning. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06histedit: Don't require argument for fcнаб1-3/+0
This is already handled correctly (per POSIX) below: When the synopsis form with -s is used: If first is omitted, the previous command shall be used. For the synopsis forms without -s: If first and last are both omitted, the previous 16 commands shall be listed or the previous single command shall be edited (based on the -l option). Test log: $ ls autogen.sh ChangeLog ... $ id uid=1000(nabijaczleweli) gid=100(users) groups=100(users) $ who nabijaczleweli pts/2 2023-02-07 18:36 (192.168.1.109) $ fc 4 , who q nabijaczleweli pts/2 2023-02-07 18:36 (192.168.1.109) $ fc -l 1 ls 2 id 3 who 4 fc $ fc -s fc -l 1 ls 2 id 3 who 4 fc 5 fc -l Reported-by: Harald van Dijk <harald@gigawatt.nl> Reported-in: https://marc.info/?l=dash&m=154707728009743&w=2 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06histedit: Don't include the current fc in out-of-range lastнаб1-0/+2
POSIX states: When a range of commands is used, it shall not be an error to specify first or last values that are not in the history list; fc shall substitute the value representing the oldest or newest command in the list, as appropriate. For example, if there are only ten commands in the history list, numbered 1 to 10: fc -l fc 1 99 shall list and edit, respectively, all ten commands. Which would seem to imply that the current fc shouldn't be included (well, in the POSIX model, no non--l fc enters the history, so that reinforces that). zsh, bash, mksh, yash all agree with this; oddly, ksh includes it. Before: $ 1 src/dash: 1: 1: not found $ 2 src/dash: 2: 2: not found $ 3 src/dash: 3: 3: not found $ 4 src/dash: 4: 4: not found $ 5 src/dash: 5: 5: not found $ 6 src/dash: 6: 6: not found $ fc 1 999 21 ,p 1 2 3 4 5 6 fc 1 999 After: $ fc 1 9999 12 ,p 1 2 3 4 5 6 Reported-by: Harald van Dijk <harald@gigawatt.nl> Reported-in: https://marc.info/?l=dash&m=154707728009743&w=2 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06histedit: Fix "fc -3" breakage on glibcнаб1-1/+2
Before: $ echo a a $ echo b b $ fc -2 -1 src/dash: 3: fc: unknown option: -2 $ fc -- -2 -1 16 ,p echo b fc -2 -1 After: $ echo a a $ echo b b $ fc -2 -1 6 ,p echo a echo b Reported-by: Harald van Dijk <harald@gigawatt.nl> Reported-in: https://marc.info/?l=dash&m=154707728009743&w=2 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06histedit: Only parse old=new for fc -sнаб1-12/+9
Before (erroneously replaced): $ a=b set ... $ fc a=b 8 , b=b set After (used as search string): $ fc a=b 8 , a=b set Reported-by: Harald van Dijk <harald@gigawatt.nl> Reported-in: https://marc.info/?l=dash&m=154707728009743&w=2 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06histedit: Fix fs -s infinite loopнаб1-4/+2
$ id 1 uid=1(daemon) gid=1(daemon) groups=1(daemon) $ fc -s 2 fc -s 2 fc -s 2 fc -s 2 fc -s 2 src/dash: 1: fc: called recursively too many times and I'm happy to call this "behaving exactly as I expected when I was typing it in", so removing the XXX. Adapted-from: NetBSD src bin/sh/histedit.c rev 1.38 by aymeric@ Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06histedit: Disallow fc -s first lastнаб1-0/+7
The POSIX SYNOPSIS (and our manual which steals it verbatim) says: fc -s [old=new] [first] and, indeed, we only use the first non-= argument instead of enforcing the usage, which is confusing. bash: 2025 ls 2026 id $ fc -s ls=who 2025 2026 who nabijaczleweli pts/2 2023-02-07 17:36 (192.168.1.109) nabijaczleweli pts/3 2023-02-07 17:38 (192.168.1.109) nabijaczleweli pts/4 2023-02-07 16:58 (192.168.1.109) nabijaczleweli pts/5 2023-02-07 17:45 (192.168.1.109) ksh93: 240 id 241 ls $ fc -s ls=who 241 240 ksh: hist: -e - requires single argument yash: 2 ls 3 id $ fc -s ls=who 2 3 fc: too many operands are specified zsh: 2 id 3 ls tarta% fc -s ls=who 3 2 fc: bad option: -s dash (before): 1 ls 2 id $ fc -s ls=who 1 2 who nabijaczleweli pts/2 2023-02-07 17:36 (192.168.1.109) nabijaczleweli pts/3 2023-02-07 17:38 (192.168.1.109) nabijaczleweli pts/4 2023-02-07 16:58 (192.168.1.109) nabijaczleweli pts/5 2023-02-07 17:45 (192.168.1.109) dash (after): 1 ls 2 id $ fc -s ls=who 1 2 src/dash: 3: fc: -s takes one history argument Adapted-from: NetBSD src bin/sh/histedit.c rev 1.38 by aymeric@ Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06options: Fix getopts handling of colon in optstrSubhaditya Nath1-1/+1
Putting a colon at the beginning of optstring to silence errors doesn't mean that the colon is a valid option. Before this patch, dash treated -: as a valid option if the optstring started with a colon. This patch fixes that problem. Test: getopts :a opt -: echo $opt$OPTARG Correct output - ?: Invalid output - : Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-06man: Fix swapped stdin/stdout for redirection operatorsForest1-4/+2
The Redirections section incorrectly claimed that <& replaces stdout and >& replaces stdin. Swapped them to make it read correctly. Ref: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_05 Both errors were followed by extra text that looked like remains of a mostly-deleted sentence. Removed those. Fixes: 6adc14a0d4e4 ("man: Clarify two redirection mechanisms") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-05var: move hashvar() calls into findvar()Ron Yorston1-10/+9
The first argument to findvar() is always obtained by a call to hashvar(), the return value of which is otherwise unused. Signed-off-by: Ron Yorston <rmy@frippery.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-05jobs: Implement pipefail optionChris Novakovic4-10/+37
With the pipefail option set, a pipeline's exit status is the exit status of the rightmost command that failed, or zero if all commands succeeded. This is planned for inclusion in the next revision of POSIX [1], although the details are yet to be finalised. The semantics of this implementation are the same as those proposed in [2], which have also been adopted by the BSD shells. [1] https://www.austingroupbugs.net/view.php?id=789 [2] https://www.austingroupbugs.net/view.php?id=789#c4115 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-04-05mail: Fix chkmail loop break conditionC. McEnroe1-1/+1
padvance_magic() returns -1 when there are no more paths left, not zero. Fixes: 4f7527f8e492 ("exec: Do not allocate stack string in padvance") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-09alias: fix name quoting in printaliasнаб1-1/+2
single_quote() over-writes the stack string, so just output the name separately first. Reported-by: Harald van Dijk <harald@gigawatt.nl> Fixes: 4ec545e8dc98 ("alias: Quote name in printalias") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08parser: Print CTLBACKQ early in parsesubHerbert Xu1-1/+1
As we are allowed to perform 4 USTPUTC's we can save a growstackstr call by adding the CTLBACKQ before we save the string. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08parser: Don't keep alloca()ing in a loop for substitutionsнаб1-11/+4
When encountering printf %010000d | tr 0 \` | sh -n printf %09999d | tr 0 \` | sh -n you want no output and "Syntax error: EOF in backquote substitution", respectively; instead, current dash segfaults. This is because the alloca for the save buffer is run, naturally, in the same function, so first it allocates one byte, then two, then ..., then appx. 4000 (for me, depends on the binary), then it segfaults on the memcpy (it's even worse, since due to alignment, it usually allocates much more for the early stuff). Nevertheless, the stack frame grows unboundedly, until we completely destroy the stack. Instead of squirreling the out block away, then letting subsequent allocations override the original, mark it used, and just re-copy it to the top of the dash stack. This increases peak memory usage somewhat (in the most pathological case ‒ the above but with three nines ‒ from 23.26 to 173.7KiB according to massif, in parsing a regular program (ratrun from ratrun 0c) from 28.68 to 29.19; a simpler program (ibid., rat) stays at 5.422; parsing libtoolize, debootstrap, and dkms (the biggest shell programs in my /[s]bin by size + by `/$( count) likewise stay the same at 12.02, 41.48, and 6.438) but it's barely measurable outside of truly pathological conditions that were a step away from a segfault previously. Link: https://bugs.debian.org/966156 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08alias: Quote name in printaliasнаб1-1/+1
This ensures even something like alias 'a|b|c=d' is output by alias as 'a|b|c'='d' instead of a|b|c='d' which is both "suitable for reinput to the shell" per POSIX and doesn't execute the aliases as code. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08redir: Use F_DUPFD_CLOEXEC instead of F_DUPFD+F_SETFD if availableнаб2-1/+17
This saves a syscall on every source file open, &c.; F_DUPFD_CLOEXEC is a mandatory part of POSIX since Issue 7 (Austin Group Interpretation 1003.1-2001 #171). Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08input: Only skip blank lines on PS1Herbert Xu1-2/+3
Blank line should not be skipped if they're found on PS2. Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08input: Check for int_pending while clearing inputHerbert Xu1-1/+2
If we receive SIGINT while clearing a partially read line from stdin we should bail out instead of continuing. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Thanks, Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08builtin: Ignore first -- in type for consistencyнаб1-3/+3
This appears to be the only remaining built-in that doesn't use nextopt() to parse its arguments (and isn't forbidden from doing so) ‒ users expect to be able to do this, and it's nice to be consistent here. Test with: type -- ls -- Correct output lists ls=/bin/ls, then --=ENOENT Wrong output lists --=ENOENT, ls=/bin/ls, --=ENOENT Fixes: https://bugs.debian.org/870317 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08builtin: Ignore first -- in getopts per POSIXнаб1-0/+3
Issue 7, XCU, getopts, OPTIONS reads "None.", and getopts isn't a special built-in listed in sexion 2.14 ‒ this means that XCU, 1. Introduction, 1.4 Utility Description Defaults, OPTIONS, Default Behavior applies: Default Behavior: When this section is listed as "None.", it means that the implementation need not support any options. Standard utilities that do not accept options, but that do accept operands, shall recognize "--" as a first argument to be discarded. Test with: getopts -- d: a Correct output is no output, exit 1 Wrong output errors out with d: being an invalid argument name Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08var: Do not add 1 to return value of strchrnulHerbert Xu1-2/+6
When a variable like OPTIND is unset dash may call the action function with a bogus pointer because it tries to add one to the return value of strchrnul unconditionally. Use strchr and nullstr instead. Link: https://bugs.debian.org/985478 Reported-by: наб <nabijaczleweli@nabijaczleweli.xyz> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08input: Disable lleft in SMALL modeHerbert Xu3-33/+66
Counting lleft is only necessary if history support is enabled. Therefore it can be safely disabled if SMALL is defined. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08input: Read standard input byte-wiseHerbert Xu2-10/+43
POSIX Issue 7, XCU, sh, STDIN says: When the shell is using standard input and it invokes a command that also uses standard input, the shell shall ensure that the standard input file pointer points directly after the command it has read when the command begins execution. It shall not read ahead in such a manner that any characters intended to be read by the invoked command are consumed by the shell (whether interpreted by the shell or not) or that characters that are not read by the invoked command are not seen by the shell. I.e. sh <<EOF id cat good! EOF must execute id, then execute cat, then the cat must copy "good!" to the standard output stream, and similarly sh <<"EOF" id read Q good! echo Q$Q EOF must execute id, then read "good!" into Q, then echo "Qgood!". Heretofor the output was as such: uid=1000(nabijaczleweli) gid=100(users) groups=100(users) ./dash: 3: good!: not found and as such (with -x): + id uid=1000(nabijaczleweli) gid=100(users) groups=100(users) + read Q + good! sh: 3: good!: not found + echo Q Q and a strace confirms: read(0, "id\ncat\ngood!\n", 8192) = 13 read(0, "id\nread Q\ngood!\necho Q$Q\n", 8192) = 25 Reading the standard input byte-by-byte is the obvious solution to this issue, Just Works, and is how all of shells do it on non-seekable input (we could, theoretically, read regular files block-wise, then seek within them after parsing, but the complexity out-weighs the rarity of running sh < program; we could also do whole-line reads on teletypes in icanon mode, but, again, the gain here is miniscule for an interactive session, and the mode can change at any time, so...). Naturally, we keep reading block-wise from not-standard-input. With this patch, we observe the correct uid=1000(nabijaczleweli) gid=100(users) groups=100(users) good! and + id uid=1000(nabijaczleweli) gid=100(users) groups=100(users) + read Q + echo Qgood! Qgood! Link: https://bugs.debian.org/862907 Reported-by: наб <nabijaczleweli@nabijaczleweli.xyz> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-08input: Eat rest of line upon resetHerbert Xu1-2/+5
Interactively, sh_error() doesn't terminate, so echo "|$(printf %10000s)echo bug" | sh -i would read the first 8KiB, see that it's invalid, then jump back to the parser, which would then read and execute the rest of the line as-if it were the next line. The fix for this is to explicitly consume the rest of the invalid line, so that the next line observed is /actually/ the next line. This is difficult to trigger accidentally right now, since we consume the entire icanon line buffer at once (provided it's <8k, which it ~always is interactively), so we always observe one line at a time, but the next patch would make even "| echo bug" blow up. Reported-by: наб <nabijaczleweli@nabijaczleweli.xyz> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05man: Document ulimit -wнаб1-1/+3
And fix the synopsis. Fixes: 05c1076ba2d1 ("Initial import.)" Link: https://bugs.debian.org/850202 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05builtin: Actually accept ulimit -rVincent Lefevre1-0/+3
The original commit that added it supposes this works, but it only adds it to the ulimit -a listing and the manual, but doesn't allow it as an option. Fixes: 46abc8c6d8a5 ("[BUILTIN] Add support for ulimit -r") Link: https://bugs.debian.org/975326 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05man: Document false built-inнаб1-0/+2
Only true was documented, add false just below it (out of order, but so is true, and the grouping makes much more sense). Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05man: printf 'X, X is a byte under dashнаб1-3/+1
Multiple issues: * the encoding is not always ASCII * what ASCII code is assigned to я * dash isn't internationalised (this is nonconformant but out of scope), and uses the next /byte/; in a UTF-8 locale: $ printf %d\\n \'ą 196 $ printf %d\\n \'я 196 this is in contrast to POSIX (and bash), which says: > If the leading character is a single-quote or double-quote, > the value shall be the numeric value in the underlying codeset > of the character following the single-quote or double-quote. (i.e. mbrtowc(&val, argv[n], ...)) Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05man: Reword to avoid confusion v/v printf Ar argument[s]/argumentsнаб1-16/+13
The current wording says that given printf a b c d a is the format, c and d are processed as noted, but b is unspecified Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05man: Document kill builtinнаб1-0/+27
The manual now contains all built-ins Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05man: Note chdir being the same builtin as cdнаб1-2/+2
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05man: Document jobs builtinнаб1-0/+14
Link: https://bugs.debian.org/558607 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05man: Fix getopts documentationнаб2-5/+10
The explicit arguments were missing, also exchange expr subst for arithmetic and fix the spacing around Bell Labs Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05builtin: Don't early-exit when first hash -r is foundнаб2-5/+9
This fixes incorrectly-accepted "hash -rv" being equivalent to hash -r (well, hash -r[literally anything] being equivalent to hash -r) Also remove -v from the manual, it doesn't appear to have ever existed Link: https://bugs.debian.org/819829 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-01-05parser: Invalid redirections are run-time, not syntax errorsнаб1-1/+1
This fixes a long-standing bug where echo 'echo >&a' | sh errors out with sh: 2: Syntax error: Bad fd number despite the error being on line 1 This patch makes the error sh: 1: Bad fd number: a as expected Adapted-from: https://github.com/hvdijk/gwsh/commit/d279523041c1c380d64b6dec7760feba20bbf6b5 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-12-11Release 0.5.12.v0.5.12Herbert Xu1-1/+1
2022-12-11eval: Test evalskip before flipping status for NNOTHerbert Xu1-1/+3
On Tue, Dec 06, 2022 at 10:15:03AM +0000, Harald van Dijk wrote: > > There is a long-standing bug that may or may not be harder to fix if this > patch goes in, depending on how you want to fix it. Here's a script that > already fails on current dash. > > f() { > if ! return 0 > then : > fi > } > f > > This should return 0, and does return 0 in bash and ksh (and almost all > shells), but returns 1 in dash. > > There are a few possible ways of fixing it. Some of them rely on continuing > to conditionally set exitstatus. This can be fixed simply by testing evalskip prior to flipping the status. Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-12-11parser: Add VSBIT to ensure subtype is never zeroHerbert Xu4-3/+4
Harald van Dijk <harald@gigawatt.nl> wrote: > On 21/11/2022 13:08, Harald van Dijk wrote: >> On 21/11/2022 02:38, Christoph Anton Mitterer wrote: >>> reject_filtered_cmd() >>> { >>> reject_and_die "disallowed command${restrict_path_list:+ >>> (restrict-path: \"${restrict_path_list//|/\", \"}\")}" >>> } >>> >>> reject_filtered_cmd >>[...] >> This should either result in the ${...//...} being skipped, or the "Bad >> substitution" error. Currently, what happens instead is it attempts, but >> fails, to skip the ${...//...}. > > The reason it fails is because the word is cut off. > > Variable substitutions are encoded as a CTLVAR special character, > followed by a byte indicating the type of substitution, followed by the > rest of the substitution data. The type of substitution is the VSNORMAL, > VSMINUS, etc. seen in parser.h. An invalid substitution is encoded as a > value of 0. > > When we define a function, we clone the function body in order to > preserve it. Cloning the function body is done by cloning each node. > Cloning a "word" node (NARG) involves copying the characters that make > up the word up to and including the terminating null byte. > > These two interact badly. The invalid substitution is seen as > terminating the word, the rest of the word is not copied, but the > expansion code does not have any way of seeing that anything got cut off > and happily continues attempting to process the rest of the word. > > If dash decides to issue an error in this case, this is not a problem: > the null byte is guaranteed to be copied, and if processing is > guaranteed to stop if a null byte is encountered, everything works out. > > If dash decides to not issue an error in this case, the encoding of bad > substitutions needs to change to a non-null byte. It appears that if we > set the byte to VSNUL, the expansion logic is already able to handle it, > but I have not tested this extensively. Thanks for the analysis Harald! This patch does basically what you've described except it uses a new bit to avoid any confusion with a genuine VSNUL. Fixes: 3df3edd13389 ("[PARSER] Report substition errors at...") Reported-by: Christoph Anton Mitterer <calestyo@scientia.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Cheers, Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-12-07eval: Check eflag after redirection errorHerbert Xu1-4/+7
> > This is a POSIX violation, and quite a grave one at that: > set -e is oft[1] used to guard against precisely this type of error! > > The same happens if set -e is executed. > > All quotes POSIX.1, Issue 7, TC2: > sh, OPTIONS: > > The -a, -b, -C, -e, -f, -m, -n, -o option, -u, -v, and -x options > > are described as part of the set utility in Special Built-In > > Utilities. > > set, DESCRIPTION, -e: > > When this option is on, when any command fails (for any of the > > reasons listed in Consequences of Shell Errors or by returning an > > exit status greater than zero), the shell immediately shall exit, as > > if by executing the exit special built-in utility with no arguments, > > with the following exceptions: > > > > 1. The failure of any individual command in a multi-command pipeline > > shall not cause the shell to exit. Only the failure of the > > pipeline itself shall be considered. > > 2. The -e setting shall be ignored when executing the compound list > > following the while, until, if, or elif reserved word, a pipeline > > beginning with the ! reserved word, or any command of an AND-OR > > list other than the last. > > 3. If the exit status of a compound command other than a subshell > > command was the result of a failure while -e was being ignored, > > then -e shall not apply to this command. > > XCU, 2.9.4: Shell Command Language, Shell Commands, Compound Commands: > The while Loop: > > The format of the while loop is as follows: > > > > while compound-list-1 > > do > > compound-list-2 > > done > (until is equivalent). > The if Conditional Construct: > > The format for the if construct is as follows: > > > > if compound-list > > then > > compound-list > > [elif compound-list > > then > > compound-list] ... > > [else > > compound-list] > > fi > > It follows, therefore, that > * Exception 1. does not apply as there is no pipeline > * Exception 2. does not apply, as the redirection does /not/ follow > "while" or "if" directly and is /not/ part of the conditional > compound-list > * in the "for" case, there is no such provision, so this is likely not > a confusion w.r.t. the conditional compound-lists > * Exception 3. does not apply as -e was not being ignored while the > compound commands were being executed (indeed, the compound commands > do not run at all, as evidenced by the program terminating) > > [1]: https://salsa.debian.org/glibc-team/glibc/-/merge_requests/6#note_329899 > ----- End forwarded message ----- Yes we should check the exit status after redirections. Reported-by: наб <nabijaczleweli@nabijaczleweli.xyz> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-12-07eval: Always set exitstatus in evaltreeHerbert Xu1-6/+7
There is no harm in setting exitstatus unconditionally in evaltree. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-12-07expand: Add ifsfree to expand to fix a logic error that causes a buffer ↵Herbert Xu4-6/+15
over-read On Mon, Jun 20, 2022 at 02:27:10PM -0400, Alex Gorinson wrote: > Due to a logic error in the ifsbreakup function in expand.c if a > heredoc and normal command is run one after the other by means of a > semi-colon, when the second command drops into ifsbreakup the command > will be evaluated with the ifslastp/ifsfirst struct that was set when > the here doc was evaluated. This results in a buffer over-read that > can leak the program's heap, stack, and arena addresses which can be > used to beat ASLR. > > Steps to Reproduce: > First bug: > cmd args: ~/exampleDir/example> dash > $ M='AAAAAAAAAAAAAAAAA' <note: 17 A's> > $ q00(){ > $ <<000;echo > $ ${D?$M$M$M$M$M$M} <note: 6 $M's> > $ 000 > $ } > $ q00 <note: After the q00 is typed in, the leak > should be echo'd out; this works with ash, busybox ash, and dash and > with all option args.> > > Patch: > Adding the following to expand.c will fix both bugs in one go. > (Thank you to Harald van Dijk and Michael Greenberg for doing the > heavy lifting for this patch!) > ========================== > --- a/src/expand.c > +++ b/src/expand.c > @@ -859,6 +859,7 @@ > if (discard) > return -1; > > +ifsfree(); > sh_error("Bad substitution"); > } > > @@ -1739,6 +1740,7 @@ > } else > msg = umsg; > } > +ifsfree(); > sh_error("%.*s: %s%s", end - var - 1, var, msg, tail); > } > ========================== Thanks for the report! I think it's better to add the ifsfree() call to the exception handling path as other sh_error calls may trigger this too. Reported-by: Alex Gorinson <algore3698@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-12-07expand: Always quote caret when using fnmatchHerbert Xu3-28/+54
This patch forces ^ to be a literal when we use fnmatch. In order to allow for the extra space to quote the caret, the function _rmescapes will allocate up to twice the memory if the flag RMESCAPE_GLOB is set. Fixes: 7638476c18f2 ("shell: Enable fnmatch/glob by default") Reported-by: Christoph Anton Mitterer <calestyo@scientia.org> Suggested-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-12-07input: Remove special case for unget EOFRon Yorston1-7/+4
Commit 17db43b5841504b694203952fb0e82246c06a97f (input: Allow two consecutive calls to pungetc) ensures that EOF is handled like any other character with respect to unget. As a result it's possible to remove the special case for unget of EOF in preadbuffer. Signed-off-by: Ron Yorston <rmy@frippery.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2021-09-03parser: Fix VSLENGTH parsing with trailing garbageHerbert Xu2-1/+5
On Sat, Jun 19, 2021 at 02:44:46PM +0200, Denys Vlasenko wrote: > > CTLVAR and CTLBACKQ are not properly handled if encountered > inside {$#...}. Testcase: > > dash -c "`printf 'echo ${#1\x82}'`" 00 111 222 > > It should execute "echo ${#1 <byte 0x82> }" and thus print "3" > (the length of $1, which is "111"). > > Instead, it segfaults. > > (Ideally, it should fail since "1 <byte 0x82>" is not a valid > variable name, but currently dash accepts e.g. "${#1abc}" > as if it is "${#1}bc". A separate, less serious bug...). In fact these two bugs are one and the same. This patch fixes both by detecting the invalid substitution and not emitting it into the node tree. Incidentally this reveals a bug in how we parse ${#10} that got introduced recently, which is also fixed here. Reported-by: Denys Vlasenko <vda.linux@googlemail.com> Fixes: 7710a926b321 ("parser: Only accept single-digit parameter...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2021-06-04shell: Call CHECK_DECL on stat64Herbert Xu1-2/+3
On macOS it is possible to find stat64 at link-time but not at compile-time. To make the build process more robust we should check for the header file as well as the library. Reported-by: Saagar Jha <saagar@saagarjha.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2021-06-04eval: Do not cache value of eflag in evaltreeHerbert Xu1-10/+2
Patrick Brünn <P.Bruenn@beckhoff.com> wrote: > > Since we are migrating to Debian bullseye, we discovered a new behavior > with our scripts, which look like this: >>#!/bin/sh >>cleanup() { >> set +e^M >> rmdir "" >>} >>set -eu >>trap 'cleanup' EXIT INT TERM >>echo 'Hello world!' > > With old dash v0.5.10.2 this script would return 0 as we expected it. > But since commit 62cf6955f8abe875752d7163f6f3adbc7e49ebae it returns > the last exit code of our cleanup function. > Reverting that commit gives a merge conflict, but it seems to fix _our_ > problem. As that topic appears too complex to us I want to ask the > experts here: > > Is this change in behavior intended, by dash? > > Our workaround at the moment would be: >>trap 'cleanup || true' EXIT INT TERM Thanks for the report. This is actually a fairly old bug with set -e that's just been exposed by the exit status change. What's really happening is that cleanup itself is triggering a set -e exit incorrectly because evaltree cached the value of eflag prior to the function call. This patch should fix the problem. Reported-by: Patrick Brünn <P.Bruenn@beckhoff.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Tested-by: Patrick Brünn <P.Bruenn@beckhoff.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2021-01-20jobs: Always reset SIGINT/SIGQUIT handlersHerbert Xu1-4/+2
On Fri, Jan 08, 2021 at 08:55:41PM +0000, Harald van Dijk wrote: > On 18/05/2018 19:39, Herbert Xu wrote: > > This patch adds basic vfork support for the case of a simple command. > > ... @@ -879,17 +892,30 @@ forkchild(struct job *jp, union node *n, int > > mode) > > } > > } > > if (!oldlvl && iflag) { > > - setsignal(SIGINT); > > - setsignal(SIGQUIT); > > + if (mode != FORK_BG) { > > + setsignal(SIGINT); > > + setsignal(SIGQUIT); > > + } > > setsignal(SIGTERM); > > } > > + > > + if (lvforked) > > + return; > > + > > for (jp = curjob; jp; jp = jp->prev_job) > > freejob(jp); > > } > > This leaves SIGQUIT ignored in background jobs in interactive shells. > > ENV= dash -ic 'dash -c "kill -QUIT \$\$; echo huh" & wait' > > As of dash 0.5.11, this prints "huh". Before, the subprocess process killed > itself before it could print anything. Other shells do not leave SIGQUIT > ignored. > > (In a few other shells, this also prints "huh", but in those other shells, > that is because the inner shell chooses to ignore SIGQUIT, not because the > outer shell leaves it ignored.) Thanks for catching this. I have no idea how that got in there and it makes no sense whatsoever. This patch removes the if conditional. Fixes: e94a964e7dd0 ("eval: Add vfork support") Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2021-01-20jobs: Block signals during tcsetpgrpHerbert Xu1-1/+7
Harald van Dijk <harald@gigawatt.nl> wrote: > On 19/12/2020 22:21, Steffen Nurpmeso wrote: >> Steffen Nurpmeso wrote in >> <20201219172838.1B-WB%steffen@sdaoden.eu>: >> |Long story short, after falsely accusing BSD make of not working >> >> After dinner i shortened it a bit more, and attach it again, ok? >> It is terrible, but now less redundant than before. >> Sorry for being so terse, that problem crosses my head for about >> a week, and i was totally mislead and if you bang your head >> against the wall so many hours bugs or misbehaviours in a handful >> of other programs is not the expected outcome. > > I think a minimal test case is simply > > all: > $(SHELL) -c 'trap "echo TTOU" TTOU; set -m; echo all good' > > unless I accidentally oversimplified. > > The SIGTTOU is caused by setjobctl's xtcsetpgrp(fd, pgrp) call to make > its newly started process group the foreground process group when job > control is enabled, where xtcsetpgrp is a wrapper for tcsetpgrp. (That's > in dash, the other variants may have some small differences.) tcsetpgrp > has this little bit in its specification: > > Attempts to use tcsetpgrp() from a process which is a member of > a background process group on a fildes associated with its con‐ > trolling terminal shall cause the process group to be sent a > SIGTTOU signal. If the calling thread is blocking SIGTTOU sig‐ > nals or the process is ignoring SIGTTOU signals, the process > shall be allowed to perform the operation, and no signal is > sent. > > Ordinarily, when job control is enabled, SIGTTOU is ignored. However, > when a trap action is specified for SIGTTOU, the signal is not ignored, > and there is no blocking in place either, so the tcsetpgrp() call is not > allowed. > > The lowest impact change to make here, the one that otherwise preserves > the existing shell behaviour, is to block signals before calling > tcsetpgrp and unblocking them afterwards. This ensures SIGTTOU does not > get raised here, but also ensures that if SIGTTOU is sent to the shell > for another reason, there is no window where it gets silently ignored. > > Another way to fix this is by not trying to make the shell start a new > process group, or at least not make it the foreground process group. > Most other shells appear to not try to do this. This patch implements the blocking of SIGTTOU (and everything else) while we call tcsetpgrp. Reported-by: Steffen Nurpmeso <steffen@sdaoden.eu> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2021-01-13input: Clear unget on RESETHerbert Xu1-0/+1
On Sat, Dec 19, 2020 at 02:23:44PM +0100, Denys Vlasenko wrote: > Current git: > > $ ;l > dash: 1: Syntax error: ";" unexpected > $ s > COPYING ChangeLog.O Makefile.am aclocal.m4 autom4te.cache > config.h config.log configure dash > dollar_altvalue1.tests missing stamp-h1 > ChangeLog Makefile Makefile.in autogen.sh compile > config.h.in config.status configure.ac depcomp install-sh > src trace This patch fixes it by clearing ungetc on RESET. Fixes: 17db43b58415 ("input: Allow two consecutive calls to pungetc") Reported-by: Denys Vlasenko <vda.linux@googlemail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2021-01-13shell: Fail if building --with-libedit and can't find libeditC. McEnroe1-1/+2
Previously, configure --with-libedit would only fail in the case where libedit is available but its header file histedit.h is not. Fixes: 13537aaa484b ("[BUILD] Added --with-libedit option to...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-12-23jobs: Only block in waitcmd on first runHerbert Xu1-1/+3
This patch ensures that waitcmd never blocks unless there are outstanding jobs. This could otherwise trigger a hang if children were created prior to the shell coming into existence, or if there are backgrounded children of other kinds (e.g., a here- document). Fixes: 6c691b3e5099 ("jobs: Only clear gotsigchld when waiting...") Reported-by: Michael Biebl <biebl@debian.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-12-23shell: Disable glob again as it strips traing slashesHerbert Xu1-3/+2
On Mon, Nov 16, 2020 at 01:47:48PM +1100, Herbert Xu wrote: > René Scharfe <l.s.r@web.de> wrote: > > > > on Debian testing dash eats trailing slashes of parameters that happen > > to be regular files when expanding "$@". Example: > > > > $ rm -f foo bar > > $ touch foo > > $ dash -c 'echo "$0" "$@"' baz foo/ bar/ ./ > > baz foo bar/ ./ > > In fact you just have to do > > dash -c 'echo bar\/' > > This is a bug in glob(3). It's stripping the slash. > > I guess we'll just have to disable glob again. This patch disables glob(3) by default. Reported-by: René Scharfe <l.s.r@web.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-08-28shell: Group readdir64/dirent64 with open64Herbert Xu1-4/+4
The test for open64 is separate from stat64 for macOS. However, the newly introduced tests for readdir64/dirent64 should be grouped with open64 instead of stat64 as otherwise they cause similar build failures. Reported-by: Martijn Dekker <martijn@inlv.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-07-08man: fix formattingBjarni Ingi Gislason4-33/+45
Fix formatting according to the output of "mandoc -Tlint". Overview: Start each sentence on a new line. Protect a punctuation mark in a macro call with '\&'. Trim trailing space. Add a missing comma in a row of words. Use an en-dash instead of '--' if there is space around it. An em-dash is used without space around it. Comment out ".Pp" macros that do nothing. Split long sentences after a punctuation mark. Remove a "-width ..." for a ".Bl -item" macro, as it has no influence Details: mandoc: ./src/bltin/echo.1:69:38: WARNING: new sentence, new line mandoc: ./src/bltin/echo.1:75:35: WARNING: new sentence, new line mandoc: ./src/bltin/printf.1:205:12: WARNING: skipping empty macro: No mandoc: ./src/bltin/printf.1:284:28: STYLE: whitespace at end of input line mandoc: ./src/bltin/printf.1:288:20: STYLE: whitespace at end of input line mandoc: ./src/bltin/printf.1:293:28: STYLE: whitespace at end of input line mandoc: ./src/bltin/printf.1:353:31: WARNING: new sentence, new line mandoc: ./src/bltin/printf.1:74:2: STYLE: useless macro: Tn mandoc: ./src/bltin/printf.1:111:2: STYLE: useless macro: Tn mandoc: ./src/bltin/printf.1:116:2: STYLE: useless macro: Tn mandoc: ./src/bltin/printf.1:279:2: STYLE: useless macro: Tn mandoc: ./src/bltin/printf.1:334:2: WARNING: unusual Xr punctuation: none before vis(3) mandoc: ./src/bltin/printf.1:334:2: WARNING: unusual Xr order: vis(3) after printf(9) mandoc: ./src/bltin/printf.1:348:2: STYLE: useless macro: Tn mandoc: ./src/bltin/printf.1:333:6: STYLE: referenced manual not found: Xr printf 9 mandoc: ./src/bltin/printf.1:334:6: STYLE: referenced manual not found: Xr vis 3 mandoc: ./src/bltin/test.1:46:16: WARNING: skipping empty macro: Cm mandoc: ./src/bltin/test.1:105:5: STYLE: useless macro: Tn mandoc: ./src/dash.1:1180:58: WARNING: new sentence, new line mandoc: ./src/dash.1:1186:13: STYLE: whitespace at end of input line mandoc: ./src/dash.1:1194:38: WARNING: new sentence, new line mandoc: ./src/dash.1:1200:35: WARNING: new sentence, new line mandoc: ./src/dash.1:1474:71: WARNING: new sentence, new line mandoc: ./src/dash.1:1783:62: WARNING: new sentence, new line mandoc: ./src/dash.1:2061:22: WARNING: new sentence, new line mandoc: ./src/dash.1:2311:54: WARNING: new sentence, new line mandoc: ./src/dash.1:2315:63: WARNING: new sentence, new line mandoc: ./src/dash.1:37:2: WARNING: prologue macros out of order: Dt after Os mandoc: ./src/dash.1:87:2: STYLE: useless macro: Tn mandoc: ./src/dash.1:94:2: STYLE: useless macro: Tn mandoc: ./src/dash.1:343:2: STYLE: useless macro: Tn mandoc: ./src/dash.1:442:17: STYLE: verbatim "--", maybe consider using \(em mandoc: ./src/dash.1:466:2: STYLE: useless macro: Tn mandoc: ./src/dash.1:581:34: STYLE: verbatim "--", maybe consider using \(em mandoc: ./src/dash.1:583:25: STYLE: verbatim "--", maybe consider using \(em mandoc: ./src/dash.1:585:43: STYLE: verbatim "--", maybe consider using \(em mandoc: ./src/dash.1:595:11: STYLE: verbatim "--", maybe consider using \(em mandoc: ./src/dash.1:618:29: STYLE: verbatim "--", maybe consider using \(em mandoc: ./src/dash.1:697:2: WARNING: skipping paragraph macro: Pp before Bd mandoc: ./src/dash.1:1344:2: STYLE: useless macro: Tn mandoc: ./src/dash.1:1420:2: WARNING: skipping paragraph macro: Pp before Bd mandoc: ./src/dash.1:1434:2: WARNING: skipping paragraph macro: Pp before Bd mandoc: ./src/dash.1:1556:2: STYLE: useless macro: Tn mandoc: ./src/dash.1:1587:2: STYLE: useless macro: Tn mandoc: ./src/dash.1:1746:2: STYLE: useless macro: Tn mandoc: ./src/dash.1:1875:5: STYLE: useless macro: Tn mandoc: ./src/dash.1:1525:2: WARNING: skipping paragraph macro: Pp before It mandoc: ./src/dash.1:2182:2: WARNING: skipping paragraph macro: Pp before It mandoc: ./src/dash.1:2247:2: WARNING: sections out of conventional order: Sh ENVIRONMENT mandoc: ./src/dash.1:2323:11: WARNING: skipping -width argument: Bl -item mandoc: ./src/dash.1:2347:31: STYLE: consider using OS macro: Nx mandoc: ./src/dash.1:92:6: STYLE: referenced manual not found: Xr ksh 1 (2 times) mandoc: ./src/dash.1:253:6: STYLE: referenced manual not found: Xr emacs 1 mandoc: ./src/dash.1:2253:9: STYLE: referenced manual not found: Xr passwd 4 mandoc: ./src/dash.1:2330:6: STYLE: referenced manual not found: Xr csh 1 Signed-off-by: Bjarni Ingi Gislason <bjarniig@rhi.hi.is> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-07-08eval: Check nflag in evaltree instead of cmdloopHerbert Xu2-1/+4
This patch moves the nflag check from cmdloop into evaltree. This is so that nflag will be in force even if we enter the shell via a path other than cmdloop, e.g., through sh -c. Reported-by: Joey Hess <id@joeyh.name> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-07-08jobs: Fix waitcmd busy loopHerbert Xu3-3/+3
We need to clear gotsigchld in waitproc because it is used as a loop conditional for the waitcmd case. Without it waitcmd may busy loop after a SIGCHLD. This patch also changes gotsigchld into a volatile sig_atomic_t to prevent compilers from optimising its accesses away. Fixes: 6c691b3e5099 ("jobs: Only clear gotsigchld when waiting...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-07-08error: Remove USE_NORETURN ifdefHerbert Xu1-4/+0
The USE_NORETURN was added because gcc was buggy almost 20 years ago. This is no longer needed and this patch removes it. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-07-08expand: Make glob(3) interruptible by SIGINTHerbert Xu2-8/+36
If glob(3) is used then it can't be interrupted by SIGINT. This is bad when an expansion causes a large number of entries to be generated. This patch improves things by adding an int_pending check to gl_opendir call. Note that this is still not perfect, e.g., the sort would still be uninterruptible. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-06-01shell: Enable fnmatch/glob by defaultHerbert Xu1-5/+6
As fnmatch(3) and glob(3) from glibc are now working consistently, this patch enables them by default. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-06-01redir: Retry open64 on EINTRHerbert Xu4-39/+62
It is possible for open64 to block on named pipes, and therefore it can be interrupted by signals and return EINTR. We should only let it fail with EINTR if real signals are pending (i.e., it should not fail on SIGCHLD if SIGCHLD has not been trapped). This patch adds a new helper sh_open to retry the open64 call if necessary. It also calls sh_error when appropriate. Fixes: 3800d4934391 ("[JOBS] Fix dowait signal race") Reported-by: Samuel Thibault <sthibault@debian.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-06-01eval: Prevent recursive PS4 expansionHerbert Xu1-1/+7
Yaroslav Halchenko <yoh@onerussian.com> wrote: > > I like to (ab)use PS4 and set -x for tracing execution of scripts. > Reporting time and PID is very useful in this context. > > I am not 100% certain if bash's behavior (of actually running the command > embedded within PS4 string, probably eval'ing it) is actually POSIX > compliant, posh seems to not do that; but I think it is definitely not > desired for dash to just stall: > > - the script: > > #!/bin/sh > set -x > export PS4='+ $(date +%T.%N) [$$] ' > > echo "lets go" > sleep 1 > echo "done $var" > > - bash: > > /tmp > bash --posix test.sh > +export 'PS4=+ $(date +%T.%N) [$$] ' > +PS4='+ $(date +%T.%N) [$$] ' > + 09:15:48.982296333 [2764323] echo 'lets go' > lets go > + 09:15:48.987829613 [2764323] sleep 1 > + 09:15:49.994485037 [2764323] echo 'done ' > done > > > - posh: > exit:130 /tmp > posh test.sh > +export PS4=+ $(date +%T.%N) [$$] > + $(date +%T.%N) [$$] echo lets go > lets go > + $(date +%T.%N) [$$] sleep 1 > + $(date +%T.%N) [$$] echo done > done > > - dash: (stalls it set -x) > > /tmp > dash test.sh > +export PS4=+ $(date +%T.%N) [$$] > ^C^C This patch fixes the infinite loop caused by repeated expansions of PS4. Reported-by: Yaroslav Halchenko <yoh@onerussian.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-06-01parser: Get rid of PEOAHerbert Xu4-65/+67
PEOA is a special character used to mark an alias as being finished so that we don't enter an infinite loop with nested aliases. It complicates the parser because we have to ensure that it is skipped where necessary and not copied to the resulting token text. This patch removes it and instead delays the marking of aliases until the second pgetc. This has the same effect as the current PEOA code while keeping the complexities within the input code. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-06-01Release 0.5.11.v0.5.11Herbert Xu1-1/+1
2020-06-01parser: Fix double-backslash nl in old-style command subHerbert Xu1-1/+1
When handling backslashes within an old-style command substitution, we should not call pgetc_eatbnl because that would treat the next backslash character as another escape character if it was then followed by a new-line. This patch fixes it by calling pgetc. Reported-by: Matt Whitlock <dash@mattwhitlock.name> Fixes: 6bbc71d84bea ("parser: use pgetc_eatbnl() in more places") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-28shell: Fix typosMartin Michlmayr2-3/+3
Signed-off-by: Martin Michlmayr <tbm@cyrius.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-28parser: Save and restore heredoclist in expandstrHerbert Xu1-3/+7
On Sun, May 17, 2020 at 01:19:28PM +0100, Harald van Dijk wrote: > > This still does not restore the state completely. It does not clean up any > pending heredocs. I see: > > $ PS1='$(<<EOF "' > src/dash: 1: Syntax error: Unterminated quoted string > $(<<EOF ": > > > > That is, after entering the ':' command, the shell is still trying to read > the heredoc from the prompt. This patch saves and restores the heredoclist in expandstr. It also removes a bunch of unnecessary volatiles as those variables are only referenced in case of a longjmp other than one started by a signal like SIGINT. Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-15shell: Always use explicit large file APIHerbert Xu8-24/+29
There are some remaining stat/readdir calls in dash that may lead to spurious EOVERFLOW errors on 32-bit platforms. This patch changes them (as well as open(2)) to use the explicit large file API. Reported-by: Tatsuki Sugiura <sugi@nemui.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-15input: Fix compiling against libedit with -fno-commonJeroen Roovers1-4/+0
With -fno-common, which will be enabled by default in GCC 10, we see this error: ld: input.o:(.bss+0x0): multiple definition of `el'; histedit.o:(.bss+0x8): first defined here To fix this, simply remove the definition as it is not needed. Signed-off-by: Jeroen Roovers <jer@gentoo.org> Signed-off-by: Mike Gilbert <floppym@gentoo.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-15shell: mktokens relative TMPDIRMichael Greenberg1-7/+9
The mktokens script fails when /tmp isn't writable (e.g., when building in a sandbox with a different TMPDIR). Replace absolute references to /tmp to relative references to TMPDIR. If TMPDIR is unset or null, default to /tmp. The mkbuiltins script was already hardened to work relative to TMPDIR, also defaulting to /tmp. v2 ensures that TMPDIR is quoted. v3 adds an extra quotation that prevents extra pathname expansions. Signed-off-by: Michael Greenberg <michael.greenberg@pomona.edu> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-15expand: Remove unused expandmeta() flag parameterDenys Vlasenko1-6/+4
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-15parser: Fix alias expansion after heredoc or newlinesHerbert Xu1-2/+5
This script should print OK: alias a="case x in " b=x a b) echo BAD;; esac alias BEGIN={ END=} BEGIN cat <<- EOF > /dev/null $(:) EOF END : <<- EOF && $(:) EOF BEGIN echo OK END However, because the value of checkkwd is either zeroed when it shouldn't, or isn't zeroed when it should, dash currently gets it wrong in every case. This patch fixes it by saving checkkwd and zeroing it where needed. Suggested-by: Harald van Dijk <harald@gigawatt.nl> Reported-by: Harald van Dijk <harald@gigawatt.nl> Reported-by: Martijn Dekker <martijn@inlv.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-15parser: Catch errors in expandstrHerbert Xu1-6/+24
On Fri, Dec 13, 2019 at 02:51:34PM +0000, Simon Ser wrote: > Just noticed another dash bug: when setting invalid PS1 values dash > enters an infinite loop. > > For instance, setting PS1='$(' makes dash print many of these: > > dash: 1: Syntax error: end of file unexpected (expecting ")") > > It would be nice to fallback to the default PS1 value on error. This patch fixes it by using the literal value of PS1 should an error occur during expansion. On Wed, Feb 26, 2020 at 09:12:04PM +0000, Ron Yorston wrote: > > There's another case that should be handled. PS1='`xxx(`' causes the > shell to exit because the old-style backquote leaves an additional file > on the stack. Ron's change has been folded into this patch. Reported-by: Simon Ser <contact@emersion.fr> Reported-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-05-15parser: Fix handling of empty aliasesHerbert Xu1-19/+10
Dash was incorrectly handling empty aliases. When attempting to use an empty alias with nothing else, I'm (incorrectly) prompted for more input: ``` $ alias empty='' $ empty > ``` Other shells (e.g., bash, yash) correctly handle the lone, empty alias as an empty command: ``` $ alias empty='' $ empty $ ``` The problem here is that we incorrectly enter the loop eating TNLs in readtoken(). This patch fixes it by setting checkkwd correctly. Reported-by: Michael Greenberg <michael.greenberg@pomona.edu> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-04-29jobs: Fix infinite loop in waitprocHerbert Xu1-9/+23
After we changed the resetting of gotsigchld so that it is only done if jp is NULL, we can now get an infinite loop in waitproc if gotsigchld is set but there is no outstanding child because everything had been waited for previously without gotsigchld being zeroed. This patch fixes it by always zeroing gotsigchld as we did before. The bug that the previous patch was trying to fix is now resolved by switching the blocking mode to DOWAIT_NORMAL after the specified job has been completed so that we really do wait for all outstanding dead children. Reported-by: Harald van Dijk <harald@gigawatt.nl> Fixes: 6c691b3e5099 ("jobs: Only clear gotsigchld when waiting...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-04-29var: Remove poplocalvars() always-zero argument, make it staticDenys Vlasenko2-21/+4
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-04-29jobs: Rename DOWAIT_NORMAL to DOWAIT_NONBLOCKDenys Vlasenko1-4/+4
To make it clearer what it is doing: nonblocking wait() Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-04-29builtin: Fix seconds part of times(1)Herbert Xu1-9/+21
The seconds part of the times(1) built-in is wrong as it does not exclude the minutes part of the result. This patch fixes it. This problem was first noted by Michael Greenberg who also sent a similar patch. Reported-by: Michael Greenberg <michael.greenberg@pomona.edu> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-04-29redir: Clear saved redirections in subshellHerbert Xu13-57/+54
When we enter a subshell we need to drop the saved redirections as otherwise a subsequent unwindredir could produce incorrect results. This patch does this by simply clearing redirlist. While we could actually free the memory underneath for subshells it isn't really worth the trouble for now. In order to ensure that this is done in every place where we enter a subshell, this patch adds a new mkinit hook called forkreset. The calls closescript, clear_traps and reset_handler are also added to the forkreset hook. This fixes a bug where the first two functions weren't called if we enter a subshell without forking. Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-01-20shell: delete AC_PROG_YACCFangrui Song1-1/+0
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-01-20parser: Only accept single-digit parameter expansion outside of bracesHerbert Xu1-1/+1
On Thu, Apr 25, 2019 at 01:39:52AM +0000, Michael Orlitzky wrote: > The POSIX spec says, > > The parameter name or symbol can be enclosed in braces, which are > optional except for positional parameters with more than one digit or > when parameter is a name and is followed by a character that could be > interpreted as part of the name. > > However, dash seems to diverge from that behavior when we get to $10: > > $ cat test.sh > echo $10 > > $ dash ./test.sh one two three four five six seven eight nine ten > ten > > $ bash ./test.sh one two three four five six seven eight nine ten > one0 This patch should fix the problem. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-01-20expand: Fix trailing newlines processing in backquote expandingNikolai Merinov1-1/+1
According to POSIX.1-2008 we should remove newlines only at the end of the substitution. Newlines-only substitions causes dash to remove newlines before beggining of the substitution. The following code: cat <<END 1 $(echo "") 2 END prints "1<newline>2" instead of expected "1<newline><newline>2". This patch fixes trailing newlines processing in backquote expanding. Signed-off-by: Nikolai Merinov <n.merinov@inango-systems.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2020-01-20parser: Fix old-style command substitution here-document crashHerbert Xu1-1/+1
On Wed, Jul 25, 2018 at 12:38:27PM +0000, project-repo wrote: > Hi, > I am working on a project in which I use the honggfuzz fuzzer to fuzz open > source software and I decided to fuzz dash. In doing so I discovered a > NULL pointer dereference in src/redir.ch on line 305. Following is a > backtrace as supplied by the address sanitizer: > > AddressSanitizer:DEADLYSIGNAL > ================================================================= > ==39623==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010 (pc 0x0000005768ed bp 0x7ffc00273df0 sp 0x7ffc00273c60 T0) > ==39623==The signal is caused by a READ memory access. > ==39623==Hint: address points to the zero page. > #0 0x5768ec in openhere /home/jfe/dash/src/redir.c:305:29 > #1 0x574d92 in openredirect /home/jfe/dash/src/redir.c:230:7 > #2 0x5737fe in redirect /home/jfe/dash/src/redir.c:121:11 > #3 0x576017 in redirectsafe /home/jfe/dash/src/redir.c:424:3 > #4 0x522326 in evalcommand /home/jfe/dash/src/eval.c:828:11 > #5 0x520010 in evaltree /home/jfe/dash/src/eval.c:288:12 > #6 0x5270da in evaltreenr /home/jfe/dash/src/eval.c:332:2 > #7 0x526f04 in evalbackcmd /home/jfe/dash/src/eval.c:640:3 > #8 0x539020 in expbackq /home/jfe/dash/src/expand.c:522:2 > #9 0x5332d7 in argstr /home/jfe/dash/src/expand.c:343:4 > #10 0x5322f7 in expandarg /home/jfe/dash/src/expand.c:196:2 > #11 0x528118 in fill_arglist /home/jfe/dash/src/eval.c:659:3 > #12 0x5213b6 in evalcommand /home/jfe/dash/src/eval.c:769:13 > #13 0x520010 in evaltree /home/jfe/dash/src/eval.c:288:12 > #14 0x554423 in cmdloop /home/jfe/dash/src/main.c:234:8 > #15 0x553bcc in main /home/jfe/dash/src/main.c:176:3 > #16 0x7f201c2b2a86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21a86) > #17 0x41dfb9 in _start (/home/jfe/dash/src/dash+0x41dfb9) > > AddressSanitizer can not provide additional info. > SUMMARY: AddressSanitizer: SEGV /home/jfe/dash/src/redir.c:305:29 in openhere > ==39623==ABORTING > > This bug can be reproduced by running "dash < min" where min is þhe file > attached. I was able to reproduce this bug with the current git version > and the current debian version. > > cheers > project-repo > > <<A > `<<A(` Thanks for the report! This is caused by the recent change to save/restore here-docment list around command substitutions. In doing so we must finish existing here-documents prior to restoring the old here-document list. This is done for new-style command substitutions but not for old-style. This patch fixes it by doing it for both. Reported-by: project-repo <bugs@feusi.co> Fixes: 51e2d88d6e51 ("parser: Save/restore here-documents in...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-03-28eval: Reset handler when entering a subshellHerbert Xu3-3/+13
As it is a subshell can execute code that is only meant for the parent shell when it executes a longjmp that is caught by something like evalcommand. This patch fixes it by resetting the handler when entering a subshell. Reported-by: Martijn Dekker <martijn@inlv.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-03-28expand: Fix double-decrement in argstrHerbert Xu1-1/+1
Due to a double decrement in argstr we may miss field separators at the end of a word in certain situations. Reported-by: Martijn Dekker <martijn@inlv.org> Fixes: 3cd538634f71 ("expand: Do not reprocess data when...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-03-28options: Do not set commandname in procargsHerbert Xu1-1/+0
We set commandname in procargs when we don't have to. This results in a duplicated output of arg0 when an error occurs. Reported-by: Olivier Duclos <odc@fastmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-02-25redir: Handle nested exec within REALLY_CLOSED redirectionHerbert Xu1-10/+30
The value of REALLY_CLOSED is used to avoid an unnecessary close(2) call when restoring redirections. However, as it stands it can remove a close(2) call that's actually needed. This happens when an enclosed exec(1) command leaves an open file descriptor behind. This patch fixes this by replacing REALLY_CLOSED with closed_redirs to track the current status of redirected file descriptors and leaving redirlist to only handle the previous state of redirected file descriptors. Reported-by: Martijn Dekker <martijn@inlv.org> Fixes: ce0f1900d869 ("[REDIR] Fix redirect restore on saved file...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-02-25output: Fix clang warnings about GNU old-style field designatorAntonio Ospite1-6/+6
Building with clang results in some warnings about the use of GNU old-style field designators: ----------------------------------------------------------------------- output.c:86:2: warning: use of GNU old-style field designator extension [-Wgnu-designator] nextc: 0, end: 0, buf: 0, bufsize: OUTBUFSIZ, fd: 1, flags: 0 ^~~~~~ .nextc = ... ----------------------------------------------------------------------- Fix the issue bu using C99 initializers instead. This should be safe and should not introduce any compatibility problems as it is done already in other parts of the codebase, like src/expand.c:ccmatch() and src/parser.c::readtoken1(). Signed-off-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-02-25shell: Fix clang warnings about "string plus integer"Antonio Ospite2-2/+4
Building with clang results in some warnings about integer values being added to strings: ----------------------------------------------------------------------- eval.c:1138:13: warning: adding 'int' to a string does not append to the string [-Wstring-plus-int] p = " %s" + (1 - sep); ~~~~~~^~~~~~~~~~~ eval.c:1138:13: note: use array indexing to silence this warning p = " %s" + (1 - sep); ^ & [ ] 1 warning generated. ... jobs.c:1424:16: warning: adding 'int' to a string does not append to the string [-Wstring-plus-int] str = "\"}" + !(quoted & 1); ~~~~~~^~~~~~~~~~~~~~~ jobs.c:1424:16: note: use array indexing to silence this warning str = "\"}" + !(quoted & 1); ^ & [ ] 1 warning generated. ----------------------------------------------------------------------- While the code itself is fine and the warnings are indeed harmless, fixing them also makes the semantic more explicit: what it is actually being increased is the address which points to the start of the string in order to skip the initial character when some conditions are met. Signed-off-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-02-25eval: Only restore exit status on exit/returnHerbert Xu5-8/+13
We unconditionally restore the saved status in exitreset, which is incorrect as we only want to do it for exitcmd and returncmd. This patch fixes the problem by introducing EXEND. Reported-by: Martijn Dekker <martijn@inlv.org> Fixes: da30b4b78769 ("[BUILTIN] Exit without arguments in a trap...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-02-25eval: avoid leaking memory associated with redirectionsHerbert Xu1-10/+6
The following constructs result in ever-increasing memory usage: while true; do { true; } </dev/null; done while true; do ( true; ) </dev/null; done For comparison, bash displays static memory usage in both cases. This issue was reported for BusyBox ash which is derived from dash: https://bugs.busybox.net/show_bug.cgi?id=7748 Signed-off-by: Ron Yorston <rmy@frippery.org> I have simplified evaltree so that it simply sets the stack mark unconditionally. This allows us to remove the stack marks in the functions called by evaltree. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-12-14system: Disable glibc warning on sigsetmaskHerbert Xu1-1/+10
As sigsetmask is set as deprecated in glibc this patch adds the pragmas to disable the warning in gcc around our one and only use of sigsetmask. It also disables it completely for non-gcc compilers and older gcc compilers as they may generate a warning too. Reported-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-12-14eval: Use sh_warnx instead of warnxHerbert Xu1-1/+1
This patch fixes a typo in evalbltin where warnx was used instead of sh_warnx. Reported-by: Antonio Ospite <ao2@ao2.it> Fixes: 8e43729547b5 ("eval: Report I/O error on stdout") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-12-14parser: Do not push token back before parseheredocHerbert Xu1-1/+4
When we read the first token in list() we use peektoken instead of readtoken as the following code needs to use the same token again. However, this is wrong when we're in a here-document as it will clobber the saved token without resetting the tokpushback flag. This patch fixes it by doing the tokpushback after parseheredoc and setting lasttoken again if parseheredoc was called. Reported-by: Ron Yorston <rmy@frippery.org> Fixes: 7c245aa8ed33 ("[PARSER] Simplify EOF/newline handling in...") Fixes: ee5cbe9fd6bc ("[SHELL] Optimize dash -c "command" to avoid a fork") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Tested-by: Simon Ser <contact@emersion.fr>
2018-12-14expand: Eat closing brace for length parameter expansionHerbert Xu1-0/+1
When we are doing VSLENGTH expansion, the closing brace is currently not removed in evalvar. This causes the caller argstr to terminate prematurely as it would interpret the closing brace as one that belongs to a parameter expansion at the outer level. This patch fixes it. Reported-by: Martijn Dekker <martijn@inlv.org> Fixes: 3cd538634f71 ("expand: Do not reprocess data when...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-12-14eval: Use the correct expansion mode for fd redirectionHerbert Xu1-1/+1
It has been reported that echo test >&$EMPTY_VARIABLE causes dash to segfault. This is a symptom of the bigger problem that dash tries to perform pathname expansion as well as field splitting on the word after >& and <&. This is wrong and this patch fixes it to use the same expansions as done on a normal redirection. Reported-by: Andrej Shadura <andrew.shadura@collabora.co.uk> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-12-14eval: Silence compiler warning about missing parenthesesAntonio Ospite1-1/+1
Gcc gives a warning about some missing parentheses: ----------------------------------------------------------------------- eval.c: In function ‘evaltree’: eval.c:282:15: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!status == isor || evalskip) ^~ eval.c:282:7: note: add parentheses around left hand side expression to silence this warning if (!status == isor || evalskip) ^~~~~~~ ( ) ----------------------------------------------------------------------- Add the parentheses to silence the warning. Signed-off-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-12-14shell: Enable automake silent rulesAntonio Ospite2-8/+10
Enable automake silent rules to make it easier to spot compilation problems. Silent rules will be enabled by default, but only if they are available, in order to keep compatibility with older autotools versions. Prepend the silent strings also to custom rules. Signed-off-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-12-14shell: Update configure.ac with suggestions from autoupdateAntonio Ospite1-2/+2
Apply the changes suggested by running autoupdate on the source repository: 1. Properly quote AC_INIT arguments. 2. Use AC_USE_SYSTEM_EXTENSIONS instead of AC_GNU_SOURCE. The former is a superset of the latter, and enables more options, see https://www.gnu.org/software/autoconf/manual/autoconf-2.60/html_node/Posix-Variants.html Signed-off-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-12-14eval: make traps work when "set -e" is enabledAntonio Ospite1-2/+2
When "set -e" is enabled traps are not always executed, in particular the EXIT trap is not executed when the shell exits on an unhandled error. Consider the following test script: #!/bin/dash set -e trap 'ret=$?; echo "EXIT: $ret"' EXIT trap 'exit 2' HUP INT QUIT PIPE TERM read variable By pressing Ctrl-C one would expect the EXIT trap to be called, as it is the case with other shells (bash, zsh), but dash does not do it. By calling dotrap() before jumping to the exit path when checkexit is not zero, dash behaves like other shells. Signed-off-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-11-19expand: Fix multiple issues with EXP_DISCARD in evalvarHerbert Xu1-14/+16
The commit 3cd538634f71538370f5af239f342aec48b7470b broke parameter expansion in multiple ways because the EXP_DISCARD flag wasn't set or tested for various cases: $ src/dash -c 'var=; echo ${var:+nonempty}' nonempty $ src/dash -u -c 'unset foo bar; echo ${foo+${bar}}' dash: 1: bar: parameter not set $ src/dash -c 'foo=bar; echo ${foo=BUG}; echo $foo' barBUG bar $ This patch fixes them by introducing a new discard variable that tracks whether the extra word should be discarded or not when it is parsed. Reported-by: Martijn Dekker <martijn@inlv.org> Fixes: 3cd538634f71 ("expand: Do not reprocess data when...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Reported-by: Martijn Dekker <martijn@inlv.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-11-19main: Print \n upon EOF (CTRL-D) when run interactivelyGerrit Pape1-1/+8
Exiting dash via a ^D instead of with "exit" causes dash to forget to print a newline. sh-3.1$ sh sh-3.1$ ^D sh-3.1$ dash $ sh-3.1$ It is more neat and tidy to send a newline similarly to what bash does, so it doesn't make the next prompt of the parent shell look ugly. Suggested by jidanni. Signed-off-by: Gerrit Pape <pape@smarden.org> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> [reworded the patch description] Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk> Bug-Debian: http://bugs.debian.org/476422 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-11-19eval: Report I/O error on stdoutGerrit Pape1-0/+2
ENOSPC as a result of an echo builting failing gives no diagnostic. Just as other shells, dash sets $? to 1, but aside from terminating the script, this does not inform the user what the problem is: zsh: % echo foo > /dev/full echo: write error: no space left on device bash: $ echo foo > /dev/full bash: echo: write error: No space left on device dash: $ echo foo > /dev/full [nothing] Print an error to stderr like the other shells. Suggested by Roger Leigh. Signed-off-by: Gerrit Pape <pape@smarden.org> [reworded the patch description with information from the bug] Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk> Bug-Debian: http://bugs.debian.org/690473 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-11-19builtin: Default to mktemp, not tempfileAndrej Shadura1-1/+1
Don't use tempfile, as it currently runs tempnam(), which is insecure and fails under pseudo(1). Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-11-19shell: update .gitignoreMartijn Dekker1-1/+2
Ignore .deps and .dirstamp in all directories. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29man: Problems in dash.1, sh.1, sh.distrib.1esr@thyrsus.com1-1/+1
This is automatically generated email about markup problems in a man page for which you appear to be responsible. If you are not the right person or list, please tell me so I can correct my database. See http://catb.org/~esr/doclifter/bugs.html for details on how and why these patches were generated. Feel free to email me with any questions. Note: These patches do not change the modification date of any manual page. You may wish to do that by hand. I apologize if this message seems spammy or impersonal. The volume of markup bugs I am tracking is over five hundred - there is no real alternative to generating bugmail from a database and template. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29expand: Ensure result is escaped in cvtnumHerbert Xu1-13/+14
The minus sign generated from arithmetic expansion is currently unquoted which causes anomalies when the result is used in where the quoting matters. This patch fixes it by explicitly calling memtodest on the result in cvtnum. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29memalloc: Avoid looping in growstacktoHerbert Xu2-9/+8
Currently growstackto will repeatedly call growstackblock until the requisite size is obtained. This is wasteful. This patch changes growstackblock to take a minimum size instead. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29eval: Always set localvar_stopHerbert Xu3-10/+13
The variable localvar_stop is set iff vlocal is true. gcc doesn't get this so we get a spurious warning. This patch fixes this by always calling pushlocalvars with vlocal and making it only actually do the push if vlocal is non-zero. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29expand: Do not reprocess data when expanding wordsHerbert Xu2-163/+133
Currently various paths will reprocess data when performing word expansion. For example, expari will skip backwards looking for the start of the arithmetic expansion, while evalvar will skip unexpanded words manually. This is cumbersome and error-prone. This patch fixes this by making word expansions proceed in a linear fashion. This means changing argstr and the various expansion functions such as expari and subevalvar to return the next character to be expanded. This is inspired by similar code from FreeBSD. However, we take things one step further and completely remove the manual word skipping in evalvar. This is accomplished by introducing a new EXP_DISCARD flag that tells argstr to only parse and not produce any actual expansions. Incidentally, argstr will now always NUL-terminate the expansion unless the EXP_WORD flag is set. This is because all but one caller of argstr wants the result to be NUL-termianted. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29expand: Fix skipping of command substitution when trimming in evalvarHerbert Xu1-0/+2
When we are trimming an unset variable in evalvar, any embedded command substitution that should have been skipped are not. This can cause them to be evaluated later should there be other command substitutions in the same input word. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29expand: Merge syntax/quotes in memtodest with flagsHerbert Xu2-25/+18
The function arguments syntax and quotes are both derived from the expansion flags. As syntax is only used by memtodest we do not need to maintain it outside of the function at all. The only place that uses something other than BASESYNTAX or DQSYNTAX is exptilde. However in that case DQSYNTAX has exactly the same effect as SQSYNTAX. This patch merges these two arguments into a single flags. The macro QUOTES_KEEPNUL has been renamed to EXP_KEEPNUL in order to keep the namespace separate. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29expand: Use HOME in tilde expansion when it is emptyHerbert Xu1-1/+1
Currently if HOME is set to empty tilde expansion will fail, i.e., it will remain as a literal tilde. This patch changes it to return the empty string as required by POSIX. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-08-29shell: Don't include config.h for native helpersPeter Korsgaard1-2/+1
config.h contains settings for the cross compiler (most importantly 32/64bit versions of functions), so don't include it when calling the native compiler to build the helpers. Otherwise we get build errors like: /usr/bin/gcc -include ../config.h -DBSD=1 -DSHELL -DIFS_BROKEN -g -O2 -Wall -o mkinit mkinit.c In file included from /usr/include/sys/stat.h:107, from /usr/include/fcntl.h:38, from mkinit.c:50: /usr/include/bits/stat.h:117: error: redefinition of ‘struct stat’ In file included from /usr/include/fcntl.h:38, from mkinit.c:50: /usr/include/sys/stat.h:504: error: redefinition of ‘stat’ /usr/include/sys/stat.h:455: note: previous definition of ‘stat’ was here Signed-off-by: Peter Korsgaard <peter@korsgaard.com> [baruch: apply to Makefile.am; update Peter's email address] Signed-off-by: Baruch Siach <baruch@tkos.co.il> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28builtin: Use test_access from NetBSD when faccessat is unavailableHerbert Xu1-46/+157
This patch adds the test_access code from NetBSD when faccess is unavailable. The code has been modified so that root can always read/write any file. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28eval: Add vfork supportHerbert Xu7-27/+99
This patch adds basic vfork support for the case of a simple command. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28eval: Replace with listsetvar with mklocal/setvareqHerbert Xu3-42/+29
This patch replaces listsetvar with mklocal/setvareq. As we now determine special built-in status prior to variable assignment, we no longer have to do a second pass listsetvar. Instead we will call setvareq directly instead of mklocal when necessary. In order to do this mklocal can now take a flag in order to mark a variable for export. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28eval: Fail immediately with redirections errors for simple commandHerbert Xu1-18/+18
Previously, dash would continue to perform variable expansions even if a redirection error occured. This patch changes it so that it fails immediately. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28eval: Add assignment built-in support againHerbert Xu5-75/+97
This patch adds assignment built-in support that used to exist in dash prior to 0.3.8-15. This is because it will soon be part of POSIX, and the semantics are now much better defined. Recognition is done at execution time, so even "command -- export" or "var=export; command $var" should work. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28exec: Never rehash regular built-insHerbert Xu1-5/+10
As regular (including special) built-ins can never be overridden, we should never remove them from the hash table. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28exec: Stricter pathopt parsingHerbert Xu5-55/+92
This patch changes the parsing of pathopt. First of all only %builtin and %func (with arbitrary suffixes) will be recognised. Any other pathopt will be treated as a normal directory. Furthermore, pathopt can now be specified before the directory, rather than after it. In fact, a future version may remove support for pathopt suffixes. Wherever the pathopt is placed, an optional % may be placed after it to terminate the pathopt. This is so that it is less likely that a genuine directory containing a % sign is parsed as a pathopt. Users of padvance outside of exec.c have also been modified: 1) cd(1) will always treat % characters as part of the path. 2) chkmail will continue to accept arbitrary pathopt. 3) find_dot_file will ignore the %builtin pathopt instead of trying to do a stat in the accompanying directory (which is usually the current directory). The patch also removes the clearcmdentry optimisation where we attempt to only partially flush the table where possible. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28builtin: Mark more regular built-insHerbert Xu1-4/+4
This patch marks the following built-ins as regular, meaning that they cannot be overriden using PATH search: hash pwd type ulimit Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28exec: Do not allocate stack string in padvanceHerbert Xu5-26/+29
Many callers of padvance immediately free the allocated string so this patch moves the stalloc call to the caller. Instead of returning the allocated string, padvance now returns the length to allocate (this may be longer than the actual string length, even including the NUL). For the case where we would previously return NULL, we now return -1. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28memalloc: Add growstackto helperHerbert Xu4-17/+12
This patch adds the growstackto helper which repeatedly calls growstackblock until the requested size is reached. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28jobs: Replace some uses of fmtstr with stpcpy/stpncpyHerbert Xu1-8/+7
Some uses of fmtstr, particularly the ones without a format string, can be replaced with stpcpy or stpncpy. This patch does that so we don't have to introduce unnecessary format strings in order to silence compiler warnings. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28output: Fix fmtstr return valueHerbert Xu1-1/+1
The function fmtstr is meant to return the actual length of output produced, rather than the untruncated length. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28var: Set IFS to fixed value at start timeHerbert Xu3-16/+4
This patch forces the IFS variable to always be set to its default value, regardless of the environment. It also removes the long unused IFS_BROKEN code. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28parser: Save/restore here-documents in command substitutionHerbert Xu1-7/+12
This patch changes the parsing of here-documents within command substitution, both old style and new style. In particular, the original here-document list is saved upon the beginning of parsing command substitution and restored when exiting. This means that here-documents outside of command substitution can no longer be filled by text within it and vice-versa. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28jobs: Only clear gotsigchld when waiting for everythingHerbert Xu1-62/+32
The gotsigchld flag is always cleared in dowait but not all callers of dowait will wait for everything. In particular, when jp is set we only wait until the set job isn't running anymore. This patch fixes this by only clearing gotsigchld if jp is unset. It also changes the waitcmd to actually set jp which corresponds to the behaviour of bash/ksh93/mksh. The only other caller of dowait that doesn't wait for everything is the jobless reaper. This is in fact redundant now that we wait after every simple command. This patch removes it. Finally as every caller of dowait needs to wait until either the given job is not running, or until all terminated jobs have been processed, this patch moves the loop into dowait itself. Fixes: 03876c0743a5 ("eval: Reap zombies after built-in...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28mkinit: Split reset into exitreset and resetHerbert Xu6-5/+15
Previously reset was called after exitshell. This was changed so that it was called before exitshell because certain state needed to be reset in order for the EXIT trap to work. However, this caused issues because certain other states (such as local variables) should not be reset. This patch fixes this by creating a new function exitreset that is called prior to exitshell and moving reset back to its original location. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28main: Only set savestatus in exitcmdHerbert Xu1-7/+2
Currently exitcmd sets exitstatus and then savestatus if the latter was previously set. In fact, as exitcmd always raises an exception and will either end up in the setjmp call in main() or exitshell(), where exitstatus is always replaced by savestatus if set, we only need to set savestatus. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-28exec: Return 126 on most errors in shellexecHerbert Xu1-4/+4
Currently when shellexec fails on most errors the shell will exit with exit status 2. This patch changes it to 126 in order to avoid ambiguities with the exit status from a successful exec. The errors that result in 127 has also been expanded to include ENOTDIR, ENAMETOOLONG and ELOOP. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-17Release 0.5.10.2.v0.5.10.2Herbert Xu1-1/+1
2018-05-15parser: Fix incorrect eating of backslash newlinesHerbert Xu1-3/+8
With the introduction of synstack->syntax, a number of references to the syntax variable was missed during the conversion. This causes backslash newlines to be incorrectly removed in single quote context. This patch also combines these calls into a new helper function pgetc_top. Fixes: ab1cecb40478 ("parser: Add syntax stack for recursive...") Reported-by: Leah Neukirchen <leah@vuxu.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-10Release 0.5.10.1.v0.5.10.1Herbert Xu1-1/+1
2018-05-09jobs - Do not block when waiting on SIGCHLDHerbert Xu2-11/+14
Because of the nature of SIGCHLD, the process may have already been waited on and therefore we must be prepared for the case that wait may block. So ensure that it doesn't by using WNOHANG. Furthermore, multiple jobs may have exited when gotsigchld is set. Therefore we need to wait until there are no zombies left. Lastly, waitforjob needs to be called with interrupts off and the original patch broke that. Fixes: 03876c0743a5 ("eval: Reap zombies after built-in...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-05-03Release 0.5.10.v0.5.10Herbert Xu1-1/+1
2018-04-19eval: Variable assignments on functions are no longer persistentHerbert Xu1-3/+0
Dirk Fieldhouse <fieldhouse@gmx.net> wrote: > > In POSIX.1-2017 ("simultaneously IEEE Std 1003.1™-2017 and The Open > Group Technical Standard Base Specifications, Issue 7") > <http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09>, > we read under '2.9.1 Simple Commands' > > "Variable assignments shall be performed as follows: > ... > - If the command name is a standard utility implemented as a function > (see XBD Utility), the effect of variable assignments shall be as if the > utility was not implemented as a function. > ... > - If the command name is a function that is not a standard utility > implemented as a function, variable assignments shall affect the current > execution environment during the execution of the function. It is > unspecified: > > * Whether or not the variable assignments persist after the > completion of the function > > * Whether or not the variables gain the export attribute during > the execution of the function > > * Whether or not export attributes gained as a result of the > variable assignments persist after the completion of the function (if > variable assignments persist after the completion of the function)" POSIX used to require the current dash behaviour. However, you're right that this is no longer the case. This patch will remove the persistence of the variable assignment. I have considered the exporting the variables during the function execution but have decided against it because: 1) It makes the code bigger. 2) dash has never done this in the past. 3) You cannot use this portably anyway. Reported-by: Dirk Fieldhouse <fieldhouse@gmx.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19parser: Fix parameter expansion inside inner double quotesHerbert Xu1-2/+3
The parsing of parameter expansion inside inner double quotes breaks because we never look for ENDVAR while innerdq is true. echo "${x#"${x+''}"''} This patch fixes it by pushing the syntax stack if innerdq is true and we enter a new parameter expansion. This patch also fixes a corner case where a bad substitution error occurs within arithmetic expansion. Reported-by: Denys Vlasenko <vda.linux@googlemail.com> Fixes: ab1cecb40478 (" parser: Add syntax stack for recursive...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19parser: Fix parsing of ${}Herbert Xu1-2/+3
dash -c 'echo ${}' should print "Bad subtitution" but instead fails with "Syntax error: Missing '}'". This is caused by us reading an extra character beyond the right brace. This patch fixes it so that this construct only fails during expansion rather than during parsing. Fixes: 3df3edd13389 ("[PARSER] Report substition errors at...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19man: correct typos, iff -> ifMartijn Dekker1-4/+4
Op 27-03-18 om 20:23 schreef Larry Hynes: > Funny, I did wonder if it might be a contraction, but I did find > it odd that it's not mentioned or explained. I'll leave it be, if > you all are happy enough to keep it 'as is', or can resubmit if you > think it's warranted. I think the simple fact that it came up here is evidence that this is too jargony for a manual. Patch attached. - M. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19expand: Do not quote backslashes in unquoted parameter expansionHerbert Xu1-5/+4
On Mon, Mar 26, 2018 at 07:25:20PM +0200, Martijn Dekker wrote: > Op 26-03-18 om 17:38 schreef Harald van Dijk: > > And not by dash 0.5.4. Like I wrote, dash 0.5.5 had some bugs that were > > fixed in 0.5.6, which mostly restored the behaviour to match <0.5.5. > > Ah, sorry. dash 0.5.4 and earlier don't compile on my system, so they > are not included in my conveniently accessible arsenal of test shells. > > > As for my patches, that was by accident and doesn't work reliably. When > > the shell sees no metacharacters, pathname expansion is bypassed, and > > backslash isn't considered a metacharacter. Which got me to my original > > example of /de\v: there are no metacharacters in there, so the shell > > doesn't look to see if it matches anything. Which seems highly > > desirable: the shell shouldn't need to hit the file system for words not > > containing metacharacters. The only way then to get consistent behaviour > > is if the backslash is taken as quoted, so I'm not tempted to argue for > > the behaviour you're hoping for, sorry. :) Here is a better example: a="/*/\nullx" b="/*/\null"; printf "%s\n" $a $b dash currently prints /*/\nullx /*/\null bash prints /*/\nullx /dev/null You may argue the bash behaviour is inconsistent but it actually makes sense. What happens is that quote removal only applies to the original token as seen by the shell. It is never applied to the result of parameter expansion. Now you may ask why on earth does the second line say "/dev/null" instead of "/dev/\null". Well that's because it is not the quote removal step that removed the backslash, but the pathname expansion. The fact that the /de\v does not become /dev even though it exists is just the result of the optimisation to avoid unnecessarily calling stat(2). I have checked POSIX and I don't see anything that forbids this behaviour. So going back to dash yes I think we should adopt the bash behaviour for pathname expansion and keep the existing case semantics. This patch does exactly that. Note that this patch does not work unless you have already applied https://patchwork.kernel.org/patch/10306507/ because otherwise the optimisation mentioned above does not get detected correctly and we will end up doing quote removal twice. This patch also updates expmeta to handle naked backslashes at the end of the pattern which is now possible. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19shell: Add subdir-objects to AM_INIT_AUTOMAKEJason Bowen1-1/+1
I've attached a patch which adds the subdir-objects option to AM_INIT_AUTOMAKE. For a while now when I've compiled dash I received a warning from automake that there are source files in a subdirectory but that the subdir-objects automake option was not supplied. I've just been adding it myself, but I finally got around to submitting a patch. The code still compiles for now (i'm using automake 1.15.1), but warning text is rarely nice to see and, if the warning text is to be believed, then the warning will eventually become an error. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19eval: Restore input files in evalcommandHerbert Xu3-2/+12
When evalcommand invokes a command that modifies parsefile and then bails out without popping the file, we need to ensure the input file is restored so that the shell can continue to execute. Reported-by: Martijn Dekker <martijn@inlv.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19eval: Reap zombies after built-in commands and functionsHerbert Xu2-8/+11
Currently dash does not reap dead children after built-in commands or functions. This means that if you construct a loop consisting of solely built-in commands and functions, then zombies can hang around indefinitely. This patch fixes this by reaping when necessary after each built-in command and function. Reported-by: Denys Vlasenko <vda.linux@googlemail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19redir: Fix typo in noclobber codeHerbert Xu1-1/+1
The noclobber code has a typo in it that causes it to fail. This patch fixes it. Reported-by: Denys Vlasenko <vda.linux@googlemail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-19expand: Fix glibc glob(3) supportHerbert Xu1-1/+2
It's been a while since we disabled glob(3) support by default. It appears to be working now, however, we have to change our code to detect the no-match case correctly. In particular, we need to test for GLOB_NOMAGIC | GLOB_NOCHECK instead of GLOB_MAGCHAR. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-02expand: Fix buffer overflow in expandmetaHerbert Xu1-24/+33
The native version of expandmeta allocates a buffer that may be overrun for two reasons. First of all the size is 1 byte too small but this is normally hidden because the minimum size is rounded up to 2048 bytes. Secondly, if the directory level is deep enough, any buffer can be overrun. This patch fixes both problems by calling realloc when necessary. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-02builtin: Move echo space/nl handling into print_escape_strHerbert Xu1-10/+13
Currently echocmd uses print_escape_str to do everything apart from printing the spaces/newlines separating its arguments. This patch moves the actual printing into print_escape_str as well using the format parameter. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-02builtin: Fix echo performance regressionHerbert Xu1-7/+12
The commit d6c0e1e2ffbf7913ab69d51cc794d48d41c8fcb1 ("[BUILTIN] Handle embedded NULs correctly in printf") caused a performance regression in the echo built-in because every echo call now goes through the printf %b slow path where the string is always printed twice to ensure the space padding is correct in the presence of NUL characters. In fact this regression applies to printf %b as well. This is easily fixed by making printf %b take the fast path when no precision/field width modifiers are present. This patch also changes the second strchurnul call to strspn which generates slightly better code. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-02expand: Fix ghost fields with unquoted $@/$*Herbert Xu1-12/+26
Harald van Dijk <harald@gigawatt.nl> wrote: > On 22/03/2018 22:38, Martijn Dekker wrote: >> Op 22-03-18 om 20:28 schreef Harald van Dijk: >>> On 22/03/2018 03:40, Martijn Dekker wrote: >>>> This patch fixes the bug that, given no positional parameters, unquoted >>>> $@ and $* incorrectly generate one empty field (they should generate no >>>> fields). Apparently that was a side effect of the above. >>> >>> This seems weird though. If you want to remove the recording of empty >>> regions because they are pointless, then how does removing them fix a >>> bug? Doesn't this show that empty regions do have an effect? Perhaps >>> they're not supposed to have any effect, perhaps it's a specific >>> combination of empty regions and something else that triggers some bug, >>> and perhaps that combination can no longer occur with your patch. >> >> The latter is my guess, but I haven't had time to investigate it. > > Looking into it again: > > When IFS is set to an empty string, sepc is set to '\0' in varvalue(). > This then causes *quotedp to be set to true, meaning evalvar()'s quoted > variable is turned on. quoted is then passed to recordregion() as the > nulonly parameter. > > ifsp->nulonly has a bigger effect than merely selecting whether to use > $IFS or whether to only split on null bytes: in ifsbreakup(), nulonly > also causes string termination to be suppressed. That's correct: that > special treatment is required to preserve empty fields in "$@" > expansion. But it should *only* be used when $@ is quoted: ifsbreakup() > takes nulonly from the last IFS region, even if it's empty, so having an > additional zero-length region with nulonly enabled causes confusion. > > Passing quoted by value to varvalue() and not attempting to modify it > should therefore, and in my quick testing does, also work to fix the > original $@ bug. You're right. The proper fix to this is to ensure that nulonly is not set in varvalue for $*. It should only be set for $@ when it's inside double quotes. In fact there is another bug while we're playing with $@/$*. When IFS is set to a non-whitespace character such as :, $* outside quotes won't remove empty fields as it should. This patch fixes both problems. Reported-by: Martijn Dekker <martijn@inlv.org> Suggested-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-02parser: Allow newlines within parameter substitutionHerbert Xu1-1/+2
On Fri, Mar 16, 2018 at 11:27:22AM +0800, Herbert Xu wrote: > On Thu, Mar 15, 2018 at 10:49:15PM +0100, Harald van Dijk wrote: > > > > Okay, it can be trivially modified to something that does work in other > > shells (even if it were actually executed), but gets rejected at parse time > > by dash: > > > > if false; then > > : ${$+ > > } > > fi > > That's just a bug in dash's parser with ${} in general, because > it bombs out without the if clause too: > > : ${$+ > } This patch fixes the parsing of newlines with parameter substitution. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-04-02expand: Fix bugs with words connected to the right of $@Herbert Xu1-5/+8
On Sun, Mar 04, 2018 at 12:44:59PM +0100, Harald van Dijk wrote: > > command: set -- a ""; space=" "; printf "<%s>" "$@"$space > bash: <a><> > dash 0.5.8: <a>< > > dash 0.5.9.1: <a>< > > dash patched: <a><> This is actually composed of two bugs. First of all our tracking of quotemark is wrong so anything after "$@" becomes quoted. Once we fix that then the problem is that the first space character after "$@" is not recognised as an IFS. This patch fixes both. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-25Revert "[BUILTIN] Remove unnecessary restoration of format string in printf"Herbert Xu1-0/+1
This reverts commit 7bb413255368e94395237d789f522891093c5774. The commit breaks printf with more than argument. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-22parser: Fix backquote support in here-document EOF markHerbert Xu1-0/+5
Currently using backquotes in a here-document EOF mark is broken because dash tries to do command substitution on it. This patch fixes it by checking whether we're looking for an EOF mark during tokenisation. Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-22shell: provide .gitignoreMartijn Dekker1-0/+41
Here's a .gitignore file for the convenience of casual git users. - M. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-22parser: Fix single-quoted patterns in here-documentsHerbert Xu1-1/+2
The script x=* cat <<- EOF ${x#'*'} EOF prints * instead of nothing as it should. The problem is that when we're in sqsyntax context in a here-document, we won't add CTLESC as we should. This patch fixes it: Reported-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-22parser: Add syntax stack for recursive parsingHerbert Xu3-85/+120
Without a stack of syntaxes we cannot correctly these two cases together: "${a#'$$'}" "${a#"${b-'$$'}"}" A recursive parser also helps in some other corner cases such as nested arithmetic expansion with paratheses. This patch adds a syntax stack allocated from the stack using alloca. As a side-effect this allows us to remove the naked backslashes for patterns within double-quotes, which means that EXP_QPAT also has to go. This patch also fixes removes any backslashes that precede right braces when they are present within a parameter expansion context, and backslashes that precede double quotes within inner double quotes inside a parameter expansion in a here-document context. The idea of a recursive parser is based on a patch by Harald van Dijk. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-22parser: use pgetc_eatbnl() in more placesHarald van Dijk1-38/+21
dash has a pgetc_eatbnl function in parser.c which skips any backslash-newline combinations. It's not used everywhere it could be. There is also some duplicated backslash-newline handling elsewhere in parser.c. Replace most of the calls to pgetc() with calls to pgetc_eatbnl() and remove the duplicated backslash-newline handling. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-22builtin: Greater resolution in test -nt / test -otMartijn Dekker2-0/+30
Op 07-03-18 om 15:46 schreef Martijn Dekker: > Op 06-03-18 om 09:19 schreef Herbert Xu: >> On Thu, Jun 22, 2017 at 10:30:02AM +0200, Petr Skočík wrote: >>> would you be willing to pull something like this? > [...] >>> I could use greater resolution in `test -nt` / `test -ot`, and st_mtim >>> field is standardized under POSIX.1-2008 (or so stat(2) says). >> >> Sure. But your patch is corrupted. > > Fixed patch attached. > > But I wouldn't apply it as is. My system does not have st_mtim. So I > think it needs a configure test and a fallback to the old method. Here's an attempt to make that happen. See attached. - M. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-10mystring: fix "Illegal number" on FreeBSD & macOS for x=; echo $((x))Martijn Dekker1-1/+1
Op 07-03-18 om 06:26 schreef Herbert Xu: > Martijn Dekker <martijn@inlv.org> wrote: >> >>> Since base is always a constant 0 or a constant 10, never a >>> user-provided value, the only error that strtoimax will ever report on >>> glibc systems is ERANGE. Checking only ERANGE therefore preserves the >>> glibc behaviour, and allows the exact same set of errors to be detected >>> on non-glibc systems. >> >> That makes sense, thanks. > > Could you resend your patch with this change please? OK, see below. - M. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-10expand: 'nolog' and 'debug' options cause "$-" to wreak havocMartijn Dekker1-1/+1
Op 29-03-17 om 20:02 schreef Martijn Dekker: > Bug: if either the 'nolog' or the 'debug' option is set, trying to > expand "$-" silently aborts parsing of an entire argument. > > $ dash -o nolog -c 'set -fuC; echo "|$- are the options|"; \ > set +o nolog; echo "|$- are the options|"' > | > |uCf are the options| > $ dash -o debug -c 'set -fuC; echo "|$- are the options|"; \ > set +o debug; echo "|$- are the options|"' > | > |uCf are the options| This turned out to be easy to fix. The routine producing the "$-" expansion failed to skip options for which there is no option letter, but only a long-form name. In dash, 'nolog' and 'debug' are currently the only two such options. Patch below. - Martijn Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-10histedit: fix build with musl libcBaruch Siach1-0/+1
musl libc defines the optreset BSD extension only in getopt.h. This fixes the following build failure: histedit.c: In function 'histcmd': histedit.c:220:2: error: 'optreset' undeclared (first use in this function) optreset = 1; optind = 1; /* initialize getopt */ ^~~~~~~~ Signed-off-by: Baruch Siach <baruch@tkos.co.il> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-10expand: Remove dependency on fmatch.h if it does not exitRink Springer1-0/+2
[ Ugh; forgot to attach patch - apologies, I need more coffee ] Dear all, Attached is a trivial patch that removes the assumption that fnmatch.h is available - the configure script already checks for fnmatch(3) and supplies its own implementation if necessary, but fnmatch.h is always included. Let me know what you think. Regards, Rink Do not assume we can include fnmatch.h Signed-off-by: Rink Springer <rink@rink.nu> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-10input: Fix here-document redirection with vi/emacs onHarald van Dijk1-1/+5
On 27/06/17 16:29, Zando Fardones wrote: > Hello, > > I think I've found a bug when using the here-document redirection in > an interactive shell. What basically happens is that you can't see the > command output if you set the "vi" or "emacs" options. That's not quite what happens: the here-document contents got lost, so there is no command output to see. Nice find. The problem is that getprompt() is implicitly called by el_gets(). This messes with the memory used by the parser to store the here-document's contents. In the non-emacs/vi case, the prompt is explicitly written by setprompt(), which wraps the getprompt() call in a pushstackmark()/popstackmark() pair to restore the state so that parsing can continue. But when getprompt() is called by el_gets(), it knows nothing about this. The whole call to el_gets() can be surrounded by another pushstackmark()/popstackmark() pair to solve the problem, as attached. Cheers, Harald van Dijk Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-10man: Small cleanup for Command Line EditingLarry Hynes1-4/+3
Jilles Tjoelker <jilles@stack.nl> wrote: > On Sat, Jun 17, 2017 at 03:53:26PM +0100, Larry Hynes wrote: >> src/dash.1, under Command Line Editing, states: >> It's similar to vi: typing <ESC> will throw you into command >> VI command mode. >> - There appears to be no need for both occurrences of 'command' >> - I can't see a reason for VI to be capitalised >> - 'will throw you into' seems a little... enthusiastic >> Following diff changes it to >> It's similar to vi: typing <ESC> enters vi command mode. >> diff --git a/src/dash.1 b/src/dash.1 >> index 8b8026d..f35d89d 100644 >> --- a/src/dash.1 >> +++ b/src/dash.1 >> @@ -2232,7 +2232,7 @@ enabled, sh can be switched between insert mode and command mode. >> The editor is not described in full here, but will be in a later document. >> It's similar to vi: typing >> .Aq ESC >> -will throw you into command VI command mode. >> +enters vi command mode. >> Hitting >> .Aq return >> while in command mode will pass the line to the shell. > I agree. If you're changing things here anyway, I suggest getting rid of > the contraction as well (changing It's to It is). The fairly formal > style of man pages avoids contractions, just like it avoids "you". > The reference to the "later document" can probably be removed as well, > since said document does not exist yet after many years. Hi Revised diff, below, expands the contraction, deletes reference to 'later document' and changes 'place' to 'places' in the following: The command ‘set -o vi’ enables vi-mode editing and place sh into vi insert mode. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-10builtin: describe_command - fix incorrect pathHarald van Dijk1-4/+11
Hi, On 26/05/17 09:04, Youfu Zhang wrote: > $ PATH=/extra/path:/usr/sbin:/usr/bin:/sbin:/bin \ >> sh -xc 'command -V ls; command -V ls; command -Vp ls; command -vp ls' > + command -V ls > ls is /bin/ls > + command -V ls > ls is a tracked alias for /bin/ls > + command -Vp ls > ls is a tracked alias for (null) > + command -vp ls > Segmentation fault (core dumped) > > describe_command should respect `path' argument. Looking up in the hash table > may gives incorrect index in entry.u.index and finally causes incorrect output > or SIGSEGV. True, but only when a path is passed in. If the default path is used, looking up in the hash table is correct, and printing tracked aliases is intentional. If it's desirable to drop that feature, then it should be dropped completely, code shouldn't be left in that can no longer be used. But it's possible to keep it working: how about this instead? Signed-off-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-03-10trap: Globally rename pendingsigs to pending_sigDenys Vlasenko4-9/+9
This variable does not contain "sigs" (plural). It contains either 0 or (one) signal number of a pending signal. For someone unfamiliar with this code, "pendingsigs" name is confusing - it hints at being an array or bit mask of pending singnals. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> CC: dash@vger.kernel.org Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2016-09-23Release 0.5.9.1.v0.5.9.1Herbert Xu1-1/+1
2016-09-23expand - Fix dangling left square brackets in patternsHerbert Xu1-2/+3
When there is an unmatched left square bracket in patterns, pmatch will behave strangely and exhibit undefined behaviour. This patch (based on Harld van Dijk's original) fixes this by treating it as a literal left square bracket. Reported-by: Olof Johansson <olof@ethup.se> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2016-09-02builtin: Fix echo -n early terminationHerbert Xu1-1/+1
The commit 7a784244625d5489c0fc779201c349555dc5f8bc ("[BUILTIN] Simplify echo command") broke echo -n by making it always terminate after printing the first argument. This patch fixes this by only terminating when we have reached the end of the arguments. Fixes: 7a784244625d ("[BUILTIN] Simplify echo command") Reported-by: Luigi Tarenga <luigi.tarenga@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2016-09-02builtin: Fix handling of trailing IFS white spacesHerbert Xu3-60/+83
The read built-in does not handle trailing IFS white spaces in the right way, when there are more fields than variables. Part of the problem is that this case is handled outside of ifsbreakup. Harald van Dijk wrote a patch to fix this by moving the magic into ifsbreakup itself. This patch further reorganises the ifsbreakup loop by having only one loop over the whole string. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Tested-by: Harald van Dijk <harald@gigawatt.nl>
2016-09-02eval: Return status in eval functionsHerbert Xu3-67/+80
The exit status is currently clobbered too early for case statements and loops. This patch fixes it by making the eval functions return the current exit status and setting them in one place -- evaltree. Harald van Dijk pointed out a number of bugs in the original patch. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2016-09-02jobs: Handle string-based job descriptorsStephen Kitt1-3/+5
When looking for a job using a string descriptor, e.g. fg %man the relevant loop in src/jobs.c only ever exits to the err label. With this patch, when the end condition is reached, we check whether a job was found, and if so, set things up to exit correctly via gotit. Multiple matches are already caught using the test in the match block. Signed-off-by: Stephen Kitt <steve@sk2.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2016-09-02trap: Implement POSIX.1-2008 trap reset behaviourHerbert Xu1-7/+18
Jonathan Perkin submitted a patch to fix the behaviour of trap when the first argument is an integer. Currently it is treated as a command while POSIX requires it to be treated as a signal. This patch is based on his idea but instead of adding an extra argument to decode_signal I have added a new decode_signum helper. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2016-06-07eval: Fix exit status when calling eval/dot with no commandsHarald van Dijk2-2/+4
On 17/11/2015 03:18, Gioele Barabucci wrote: > Hello, > > a bug has been filed in the Debian BTS about dash not resetting the exit > status after sourcing an empty file with the dot command. [1] > > The following test echoes "OK" with bash and "fail" with dash > > #!/bin/sh > > echo > ./empty > false > > . ./empty && echo "OK" || echo "fail" > > A similar bug in dash has been discussed and addressed in 2011 [2], but > it looks like the solution has been only partial. > > The version of dash I tested is the current git master branch, commit > 2e58422. > > [1] https://bugs.debian.org/777262 > [2] http://article.gmane.org/gmane.comp.shells.dash/531 The bug described there was about empty files. While the fix has been applied and does make dash handle empty files properly, your test doesn't use an empty file, it uses a file containing a single blank line. Unfortunately, the single blank line gets parsed by dash as a null command, null commands don't (and shouldn't) reset the exit status, and the fix you link to doesn't handle this because it sees a command has been executed and saves the exit status after executing that command as the exit status to be used by ".". I think the easiest way to fix this is to prevent null commands from affecting status in cmdloop, as attached. An alternative could be to change the outer if condition to exclude n == NULL, but I didn't do that because the change of job_warning and clearing of numeof make sense to me even for null commands. Besides, when debug tracing is enabled, null commands have a visible effect that should remain. Note that this fixes the problem with . but the same problem can be present in other locations. For example, false eval " " && echo OK || echo Fail used to print Fail, and needed the same modification in the evalstring function to make that print OK (included in the attached patch). There may be other similar bugs lurking. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2016-06-06man: Document ulimit -vGioele Barabucci1-1/+4
Document that `ulimit` can set the `RLIMIT_AS` limit (virtual memory) with the `-v` flag. Fixes: https://bugs.debian.org/78556 Reported-by: Vincent Lefevre <vincent@vinc17.net> Signed-off-by: Gioele Barabucci <gioele@svario.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2016-06-06shell: Fix build on Solaris 9Jonathan Perkin2-6/+10
Ensure dash can build in a default Solaris 9 or older environment: - Execute scripts with $SHELL rather than /bin/sh, the latter does not support e.g. "if ! .." used by mkbuiltins. - /bin/awk does not support ?: syntax, use explicit statements instead. - /bin/nl requires no spaces between options and arguments. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>