As of 509f5b0d, the build fails on Darwin/macOS, which does not have
memfd_create(2). The build fails on redir.c because the fallback for
memfd_create, which is defined in system.h, is not included. Presumably it is
the same on other systems without memfd_create.
Fixes: 509f5b0dcd71 ("redir: Use memfd_create instead of pipe")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
$ 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>
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>
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>
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>
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>
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>
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>
Buster is old-old-stable and ships dpkg 1.19.8, so we can drop these.
Especially useful when building read-only images without package manager
where maint scripts are run at build time and not at runtime.
Closes: #1057323