Upstream commit:
Date: Fri, 23 Mar 2018 18:58:47 +0800
expand: Fix ghost fields with unquoted $@/$*
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>
function old new delta
argstr 1111 1113 +2
evalvar 571 569 -2
varvalue 579 576 -3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 2/-5) Total: -3 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sat, 19 May 2018 02:39:43 +0800
var: Set IFS to fixed value at start time
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>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Wed, 4 Apr 2018 17:54:01 +0800
eval: Variable assignments on functions are no longer persistent
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>
function old new delta
evalcommand 1606 1635 +29
evalcase 313 317 +4
evalfun 280 268 -12
pushlocalvars 48 - -48
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/1 up/down: 33/-60) Total: -27 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sun, 25 Mar 2018 16:38:00 +0800
expand: Fix buffer overflow in expandmeta
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>
function old new delta
expmeta 517 635 +118
expandarg 990 996 +6
mklocal 288 290 +2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 126/0) Total: 126 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 22 Mar 2018 21:41:24 +0800
parser: Allow newlines within parameter substitution
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>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
newer bash does not drop it, most other shells too
function old new delta
unbackslash 39 57 +18
parse_stream 2753 2751 -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 18/-2) Total: 16 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream email:
parser: Fix parameter expansion inside inner double quotes
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>
function old new delta
readtoken1 2880 2898 +18
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream email:
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>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 9 Mar 2018 23:07:53 +0800
parser: Fix single-quoted patterns in here-documents
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>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This closes 10821.
Upstream patch:
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 9 Mar 2018 00:14:02 +0800
parser: Add syntax stack for recursive parsing
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>
var_bash3, var_bash4 and var_bash6 tests are updated
with the output given by bash-4.3.43
With this patch, the following tests now pass for ash:
dollar_repl_slash_bash2.tests
squote_in_varexp2.tests
squote_in_varexp.tests
var_bash4.tests
function old new delta
readtoken1 2615 2874 +259
synstack_push - 54 +54
evalvar 574 571 -3
rmescapes 330 310 -20
subevalvar 1279 1258 -21
argstr 1146 1107 -39
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/4 up/down: 313/-83) Total: 230 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu Mar 15 18:27:30 2018 +0800
parser: Fix backquote support in here-document EOF mark
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>
With added fix for quoted-ness of the EOF mark.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Part of upstream commit:
Date: Thu Mar 8 08:37:11 2018 +0100
Author: Harald van Dijk <harald@gigawatt.nl>
parser: use pgetc_eatbnl() in more places
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>
Not adding "readtoken1(pgetc_eatbnl(), DQSYNTAX..." changes, since
readtoken1() handles the "starts with backslash + newline" case itself.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Tue Mar 6 17:40:37 2018 +0000
expand: 'nolog' and 'debug' options cause "$-" to wreak havoc
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>
In bbox ash, pipefail is the option which exhibited this.
Signed-off-by: Martijn Dekker <martijn@inlv.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
It usually does not bite since bbox forces -funsigned-char build.
But for some reason void linux people disabled that.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
function old new delta
setjobctl 371 367 -4
setinputfile 226 220 -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-10) Total: -10 bytes
Based on patch by Mark Marshall <mark.marshall@omicronenergy.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Based on a patch by Mark Marshall <mark.marshall@omicronenergy.com>
function old new delta
dup_CLOEXEC - 49 +49
fcntl_F_DUPFD 46 - -46
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This implements support for the command_not_found_handle hook function, which is
useful for allowing package managers to suggest packages which could provide the
command.
Unlike bash, however, we ignore exit codes from the hook function and always return
the correct POSIX error code (EX_NOTFOUND).
function old new delta
find_command 911 990 +79
Signed-off-by: William Pitcock <nenolod@dereferenced.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Before this patch, "${v:2:0x100000001}" = "${v:2:1}",
and similarly, constructs like "${v:2:9999999999}" may give wrong result
due to int overflows.
function old new delta
substr_atoi - 43 +43
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
If the numeric argument passed to ash's 'shift' built-in is greater than
'$#' the command performs no operation and exits successfully. It should
return a non-zero exit code instead:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#shift
This is consistent with bash and hush.
function old new delta
shiftcmd 122 120 -2
Signed-off-by: Ingo van Lil <inguin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
It is always nicer to give the user some sort of indication why an
operation failed.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 30 Oct 2014 11:53:35 +0800
[PARSER] Catch variable length expansions on non-existant specials
Currently we only check special variable names that follow directly
after $ or ${. So errors such as ${#&} are not caught. This patch
fixes that by moving the is_special check to just before we print out
the special variable name.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
readtoken1 2630 2635 +5
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The POSIX standard only requires the read builtin to handle -r:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html
However, Bash introduced the option -d <DELIM> to override IFS for
just one invocation, and it is quite useful.
It is also super easy to implement in BusyBox' ash, so let's do that.
The motivation: This option is used by Git's test suite.
function old new delta
.rodata 163505 163587 +82
shell_builtin_read 1244 1289 +45
readcmd 233 259 +26
builtin_read 258 263 +5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 158/0) Total: 158 bytes
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
hush -c 'yes | head -1' was not happy.
function old new delta
tryexec 159 169 +10
pseudo_exec_argv 328 338 +10
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Based on patch by Johannes Schindelin <johannes.schindelin@gmx.de>
function old new delta
evalcommand 1447 1500 +53
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
As of 035486c75 (ash: significant overhaul of redirect saving logic,
2017-07-31), the sv_pos variable is no longer used (just assigned to,
with no further effect).
Let's just remove it.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sun, 13 Jul 2008 22:34:50 +0800
[OPTIONS] Added support for -l
This patch adds support for the -l option (login shell) as required
by the LSB.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
It's a bit bigger, but gets rid of one global variable
function old new delta
options 554 576 +22
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The fact that shell has open fds to tty and/or scripts should be
unobservable, if possible. In particular, if redirect tries to dup
one of them via ">&script_fd", it's better to pretend that script_fd
is closed, and thus redirect fails with EBADF.
Fixes these two testcase failures:
ash-redir/redir_to_bad_fd.tests
hush-redir/redir_to_bad_fd3.tests
function old new delta
redirect 1018 1129 +111
setup_redirects 250 359 +109
readtoken1 2651 2655 +4
cmdloop 185 187 +2
changepath 194 195 +1
save_fd_on_redirect 203 194 -9
evaltree 501 484 -17
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/2 up/down: 227/-26) Total: 201 bytes
text data bss dec hex filename
914553 485 6848 921886 e111e busybox_old
914754 485 6848 922087 e11e7 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
New code is similar to what hush is doing.
Make CLOSED to -1: same as dash.
popredir() loses "restore" parameter: same as dash.
COPYFD_RESTORE bit is no longer necessary.
This change fixes this interactive bug:
$ ls -l /proc/$$/fd 10>&-
ash: can't set tty process group: Bad file descriptor
ash: can't set tty process group: Bad file descriptor
[1]+ Done(2) ls -l /proc/${\$}/fd 10>&4294967295
function old new delta
unwindredir 29 27 -2
tryexec 154 152 -2
evaltree 503 501 -2
evalcommand 1369 1367 -2
cmdloop 187 185 -2
redirect 1029 1018 -11
popredir 153 123 -30
need_to_remember 36 - -36
is_hidden_fd 68 - -68
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 0/7 up/down: 0/-155) Total: -155 bytes
text data bss dec hex filename
914572 485 6848 921905 e1131 busybox_old
914553 485 6848 921886 e111e busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 27 May 2010 15:03:46 +0800
[REDIR] Fix popredir on abnormal exit from built-in
Just like the poplocalvar problem recently fixed, redirections
can also be leaked in case of an abnormal exit. This patch fixes
it using the same method as poplocalvar, by storing the previous
redirection state and restoring to that point.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 27 Dec 2007 13:54:16 +1100
[PARSER] Add FAKEEOFMARK for expandstr
Previously expandstr used the string "" to indicate that it needs to be
treated just like a here-doc except that there is no terminator. However,
the string "" is in fact a valid here-doc terminator so now that we deal
with it correctly expandstr no longer works in the presence of new-lines
in the prompt.
This patch introduces the FAKEEOFMARK macro which does not equal any
real EOF marker but is distinct from the NULL pointer which is used to
indicate non-here-doc contexts.
Thanks to Markus Triska for reporting this regression.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Unfortunately, I did not find the failing example for this old fix.
I also tweaked the code which was added by this commit:
"
Date: Mon Sep 24 18:30:02 2007 +0000
ash: fix prompt expansion (Natanael Copa <natanael.copa@gmail.com>)
"
since other parts of code do expect expandstr() to use DQSYNTAX, not PSSYNTAX.
function old new delta
parse_stream 2609 2634 +25
setprompt_if 128 133 +5
read_profile 32 37 +5
evalcommand 1334 1339 +5
expandstr 122 120 -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 40/-2) Total: 38 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream comment:
Date: Sun, 11 Nov 2007 14:21:23 +0800
[PARSER] Removed noexpand/length check on eofmark
On Tue, Oct 30, 2007 at 04:23:35AM +0000, Oleg Verych wrote:
>
> } 8<<""
> ======================
Actually this (the empty delim) only works with dash by accident.
I've tried bash and pdksh and they both terminate on the first
empty line which is what you would expect rather than EOF. The
real Korn shell does something completely different.
I've fixed this in dash to conform to bash/pdksh.
> In [0] it's stated, that delimiter isn't evaluated (expanded), only
> quoiting must be checked. That if() seems to be completely bogus.
OK I agree. The reason it was there is because the parser would
have already replaced the dollar sign by an internal representation.
I've fixed it properly with this patch.
Test case:
cat <<- $a
OK
$a
cat <<- ""
OK
echo OK
Old result:
dash: Syntax error: Illegal eof marker for << redirection
OK
echo OK
New result:
OK
OK
OK
function old new delta
parsefname 227 152 -75
readtoken1 2819 2651 -168
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-243) Total: -243 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The '%m' conversion specifier prints an error message based on the
current value of 'errno'. It is available in the GNU C library,
Cygwin (since 2012), uClibc and musl.
It is not available in various BSDs, BSD-derived systems (MacOS,
Android) or Microsoft Windows.
Use a symbol defined in platform.h to control how error messages
can be formatted to display the 'errno' message. On platforms that
support it use '%m'; on other platforms use '%s' and strerror().
On platforms that have '%m' there is essentially no change in the
size of the binary. Otherwise:
function old new delta
redirect 1287 1310 +23
xtcsetpgrp 27 44 +17
dup2_or_raise 34 51 +17
setinputfile 267 275 +8
.rodata 163379 163371 -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 65/-8) Total: 57 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Defining a function alias with __attribute__ ((alias("evaltree"),__noreturn__))
is not that usual, and clang had a bug which made it misunderstand
this construct.
Switch to:
ALWAYS_INLINE NORETURN evaltreenr() { evaltree(); unreachable(); }
Older gcc's do not know unreachable(), on them we pay the price of having
a few extra calls to abort():
function old new delta
evalsubshell 151 156 +5
evalpipe 357 362 +5
argstr 1141 1144 +3
On newer gcc, code size does not change.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Tue, 6 Jul 2010 17:40:53 +0800
[VAR] Fix loss of variables when hash collides
Brian Koropoff reported that the new var patches broke the following
script:
#!/bin/dash
GDM_LANG="bar"
OPTION="foo"
unset GDM_LANG
# OPTION has mysteriously become unset
echo "$OPTION"
He correctly diagnosed this as a result of removing all variables
in the hash chain preceding the one that should be removed in
setvareq.
He also provided a patch to fix this.
This patch is based on his but without keeping the original vpp.
As a result, we now store new variables at the end of the hash
chain instead of the beginning.
To make this work, setvareq/setvar now returns the vp pointer
modified. In case they're used to unset a variable the pointer
returned is undefined. This is because mklocal needs it and
used to get it by assuming that the new variable always appear
at the beginning of the chain.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 27 May 2010 11:50:19 +0800
[VAR] Do not poplocalvars prematurely on regular utilities
The recent cmdenviron removal broke regular utilities by calling
poplocalvars too early. This patch fixes that by postponing the
poplocalvars for regular utilities until they have completed.
In order to ensure that local still works, it is now a special
built-in.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 27 May 2010 11:32:55 +0800
[VAR] Fix poplocalvar on abnormal exit from function
The new localvar code broke the abnormal exit from functions
and built-ins by not restoring the original localvar state.
This patch fixes this by storing the previous localvar state so
that we always unwind correctly in case of an abnormal exit.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Wed, 26 May 2010 18:54:19 +0800
[VAR] Replace cmdenviron with localvars
This patch replaces the cmdenviron mechanism for temporary command
variables with the localvars mechanism used by functions.
This reduces code size, and more importantly, makes the variable
assignment take effect immediately as required by POSIX.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Tue, 25 May 2010 18:14:32 +0800
[VAR] Fix poplocalvar leak
When a variable is marked as local, we set VSTRFIXED on its vp
recored. However, poplocalvar never clears this flag for variables
that were unset to begin with. Thus if you ever made an unset
variable local, it would get the VSTRFIXED bit and stick around
forever.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Mon, 24 May 2010 15:31:27 +0800
[VAR] Add localvars nesting
This patch adds localvars nesting infrastructure so we can reuse
the localvars mechanism for command evaluation.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
If STANDALONE and we run a NOEXEC applet, saved copies of redirected fds
were visible for the child. They have CLOEXEC bit, yes, but we do not exec
in this case.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 7 Jul 2011 13:58:48 +0800
[SHELL] Optimize dash -c "command" to avoid a fork
On Sun, Apr 10, 2011 at 07:36:49AM +0000, Jonathan Nieder wrote:
> From: Jilles Tjoelker <jilles@stack.nl>
> Date: Sat, 13 Jun 2009 16:17:45 -0500
>
> This change only affects strings passed to -c, when the -s option is
> not used.
>
> Use the EV_EXIT flag to inform the eval machinery that the string
> being passed is the entirety of input. This way, a fork may be
> omitted in many special cases.
>
> If there are empty lines after the last command, the evalcmd will not
> see the end early enough and forks will not be omitted. The same thing
> seems to happen in bash.
>
> Example:
> sh -c 'ps lT'
> No longer shows a shell process waiting for ps to finish.
>
> [jn: ported from FreeBSD SVN r194128. Bugs are mine.]
>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Instead of detecting EOF using the input layer, I'm going to
use the parser instead. In either case, we always have to read
ahead in order to complete the parsing of the previous node.
Therefore we always know whether there is more to come, except
in the case where we see a newline/semicolon or similar.
For the purposes of sh -c, this should be sufficient.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
evalstring 190 224 +34
ash_main 1014 1022 +8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 42/0) Total: 42 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 10 Mar 2011 16:52:13 +0800
[REDIR] Replace GPL noclobberopen code with the FreeBSD version
Replace noclobberopen() from bash with the FreeBSD code for noclobber
opens.
This also reduces code size by eliminating an unnecessary check.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
changepath 192 194 +2
localcmd 366 364 -2
expmeta 521 517 -4
redirect 1210 1135 -75
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/3 up/down: 2/-81) Total: -79 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
We fixed the problem differently than they. Let's not deviate.
Upstream commit:
Date: Thu, 27 May 2010 20:07:29 +1000
[EXPAND] Fix corruption of redirections with byte 0x81
In other ash variants, a partial implementation of ksh-like cmd >file*
adds and removes CTLESC bytes ('\x81') in redirection filenames,
preserving 8-bit transparency. Long ago, dash removed the code to add
the CTLESC bytes, but not the code to remove them, causing corruption of
filenames containing CTLESC. This commit removes the code to remove the
CTLESC bytes.
The CTLESC byte occurs frequently in UTF-8 encoded non-Latin text.
This bug has been reported various times to Ubuntu and Debian (e.g.
Launchpad Ubuntu #422298). This patch is the same as the one submitted
by Alexander Korolkov in Ubuntu #422298.
Signed-off-by: Jilles Tjoelker <jilles@stack.nl>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
changepath 194 192 -2
expandarg 1000 984 -16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-18) Total: -18 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Tue, 25 May 2010 20:55:05 +0800
[VAR] Move unsetvar functionality into setvareq
This patch moves the unsetvar code into setvareq so that we can
no have a pathological case of an unset variable hanging around
unless it has a bit pinning it like VEXPORT.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
setvareq 227 303 +76
expmeta 517 521 +4
localcmd 364 366 +2
unsetcmd 96 76 -20
unsetvar 129 7 -122
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/2 up/down: 82/-142) Total: -60 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This change fixes the build in setups where there are
no headers defining WIFSTOPPED and WSTOPSIG (where JOBS has to be
set to 0).
This partially reverts 4700fb5be (ash: make dowait() a bit more
readable. Logic is unchanged, 2015-10-09).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
$ PATH=/extra/path:/usr/sbin:/usr/bin:/sbin:/bin \
> busybox 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
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.
function old new delta
describe_command 386 313 -73
Signed-off-by: Youfu Zhang <zhangyoufu@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When using musl libc glob() a very long string can cause glob() to fail,
which leads to an out of memory error being raised by ash.
This can happen easily if a very long quoted string contains *, even
though no glob expansion should ever be performed on it (since it's
quoted).
Fix this by properly parsing control characters and escaping and only
accept unquoted metacharacters. While we're at it, unify this check for
libc and built-in glob expansion
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
bash has a feature: it restores termios after a successful wait for
a foreground job which had at least one stopped or sigkilled member.
The probable rationale is that SIGSTOP and SIGKILL can preclude task from
properly restoring tty state. Should we do this too?
A reproducer: ^Z an interactive python:
$ python
Python 2.7.12 (...)
>>> ^Z
{ python leaves tty in -icanon -echo state. We do survive that... }
[1]+ Stopped python
{ ...however, next program (python no.2) does not survive it well: }
$ python
Python 2.7.12 (...)
>>> Traceback (most recent call last):
{ above, I typed "qwerty<CR>", but -echo state is still in effect }
File "<stdin>", line 1, in <module>
NameError: name 'qwerty' is not defined
The implementation is modeled on bash code and seems to work.
However, I'm not sure we should do this. For one: what if I'd fg
the stopped python instead? It'll be confused by "restored" tty state.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Splitting these options makes it self-documenting about what
bash-compatible features we have.
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Redundant help texts (one which only repeats the description)
are deleted.
Descriptions and help texts are trimmed.
Some config options are moved, even across menus.
No config option _names_ are changed.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
commit e19923f665 deleted clearredir()
call in shellexec():
ash: [REDIR] Remove redundant CLOEXEC calls
Upstream commit:
Now that we're marking file descriptors as CLOEXEC in savefd, we no longer
need to close them on exec or in setinputfd.
but it missed one place where we don't set CLOEXEC. Fixing this.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This would makes all ash options indented inside "ash" in menuconfig.
It appears that menuconfig has a limit at tracking multiple dependency
lines like this (it looks like a "diamond problem" but I'm not sure if
it is):
---ASH <----------
/ \ ASH_OPTIMIZE_FOR_SIZE
!NOMMU <-*----SH_IS_ASH <----[OR] <--ASH_INTERNAL_GLOB
\ / ASH_RANDOM_SUPPORT
---BASH_IS_ASH <-- [...]
The kconfig-language document [1] states that:
> If a menu entry somehow depends on the previous entry, it can be
> made a submenu of it. First, the previous (parent) symbol must be
> part of the dependency list and then one of these two conditions
> must be true:
> - the child entry must become invisible, if the parent is set to 'n'
[BusyBox ash used to satisfy this, but no longer does]
> - the child entry must only be visible, if the parent is visible
[BusyBox ash configs actually satisfy this, but because of
"diamond" above this might not be easily detected]
So I found out a direct workaround: by making ash options explicitly
depend on !NOMMU, we can tell menuconfig that rule 2 above is satisfied
without any more tracking.
---------------------
/ \
!NOMMU <-*-----ASH <-------- \
\ \ \ ASH_OPTIMIZE_FOR_SIZE
*---SH_IS_ASH <---[OR]-[AND] <--ASH_INTERNAL_GLOB
\ / ASH_RANDOM_SUPPORT
--BASH_IS_ASH <- [...]
So all ash options would now be indented under "ash".
[1] "Documentation/kbuild/kconfig-language.txt" in Linux kernel source
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The commit 'ash,hush: set exit code 127 in "sh /does/not/exist" case'
only partly implemented the dash commit '[ERROR] Allow the originator
of EXERROR to set the exit status'. This resulted in incorrect error
codes for a syntax error:
$ )
$ echo $?
0
or a redirection error for a special builtin:
$ rm -f xxx
$ eval cat <xxx
$ echo $?
0
Signed-off-by: Ron Yorston <rmy@pobox.com>
Reported-by: Martijn Dekker <martijn@inlv.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The same can be done for msh, but we are probably better off just deleting it
in a next versio or two.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
In this example:
ash -c 'readonly x; echo $(command eval x=2)'
evalstring() is called after forkchild(), which calls popallfiles().
On exception, evalstring() will popfile().
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sun, 22 Feb 2009 18:10:01 +0800
[JOBS] Fix dowait signal race
This test program by Alexey Gladkov can cause dash to enter an
infinite loop in waitcmd.
#!/bin/dash
trap "echo TRAP" USR1
stub() {
echo ">>> STUB $1" >&2
sleep $1
echo "<<< STUB $1" >&2
kill -USR1 $$
}
stub 3 &
stub 2 &
until { echo "###"; wait; } do
echo "*** $?"
done
The problem is that if we get a signal after the wait3 system
call has returned but before we get to INTON in dowait, then
we can jump back up to the top and lose the exit status. So
if we then wait for the job that has just exited, then it'll
stay there forever.
I made the original change that caused this bug to fix pretty
much the same bug but in the opposite direction. That is, if
we get a signal after we enter wait3 but before we hit the kernel
then it too can cause the wait to go on forever (assuming the
child doesn't exit).
In fact this is pretty much exactly the scenario that you'll
find in glibc's documentation on pause(). The solution is given
there too, in the form of sigsuspend, which is the only way to
do the check and wait atomically.
So this patch fixes Alexey's race without reintroducing the old
bug by converting the blocking wait3 to a sigsuspend.
In order to do this we need to set a signal handler for SIGCHLD,
so the code has been modified to always do that.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
I failed to reproduce the bug (it requires precise timing), but it seems real.
function old new delta
dowait 284 463 +179
setsignal 301 326 +25
signal_handler 59 76 +17
ash_main 1481 1487 +6
localcmd 350 348 -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 227/-2) Total: 225 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit 1:
Date: Sun, 22 Feb 2009 18:16:13 +0800
[SIGNAL] Remove EXSIG
Now that waitcmd no longer uses EXSIG we can remove it.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Upstream commit 2:
Date: Thu, 2 Oct 2014 21:07:55 +0800
[ERROR] Set exitstatus in onint
Currently the exit status when we receive SIGINT is set in evalcommand
which means that it doesn't always get set. For example, if you press
CTRL-C at the prompt of an interactive dash, the exit status is not
set to 130 as it is in many other Bourne shells.
This patch fixes this by moving the setting of the exit status into
onint which also simplifies evalcommand.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Upstream commit 3:
Date: Fri, 3 Oct 2014 14:07:07 +0800
[EVAL] Do not clobber exitstatus in evalcommand
All originators of EXERROR have been setting the exitstatus for
a while now. So it is no longer appropriate to set it explicitly
in evalcommand.
In fact doing so may cause the original exitstatus to be lost.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Last three coomits:
function old new delta
waitcmd 186 224 +38
dowait 276 284 +8
waitforjob 104 107 +3
localcmd 348 350 +2
showjobs 64 61 -3
forkshell 263 260 -3
raise_interrupt 93 67 -26
blocking_wait_with_raise_on_sig 40 - -40
evalcommand 1264 1208 -56
evaltree 809 498 -311
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This loses an insignificant optimization, but may allow backporting
of some recent-ish dash fixes.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit should have deleted these two statements:
commit c0e007663d
Author: Ron Yorston <rmy@pobox.com>
Date: Thu Oct 29 11:30:55 2015 +0000
ash: simplify EOF/newline handling in list parser
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Wed, 8 Sep 2010 20:07:26 +0800
[EXPAND] Fix ifsfirst/ifslastp leak
As it stands expandarg may return with a non-NULL ifslastp which
then confuses any subsequent ifsbreakup user that doesn't clear
it directly.
What's worse, if we get interrupted before we hit ifsfree in
expandarg we will leak memory.
This patch fixes this by always calling ifsfree in expandarg
thus ensuring that ifslastp is always NULL on the normal path.
It also adds an ifsfree call to the RESET path to ensure that
memory isn't leaked.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Fallout 1:
Date: Mon, 18 Oct 2010 10:55:42 +0800
[EXPAND] Fix ifsfirst/ifslastp leak in casematch
The commit f42e443bb511ed3224f09b4fcf0772438ebdbbfa
[EXPAND] Fix ifsfirst/ifslastp leak
revealed yet another ifsfirst/ifslastp leak in casematch.
Previously it was hidden because ifsfirst/ifslastp was cleared
unconditionally on entry (which caused the leakage of those
entries).
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Fallout 2:
Date: Sun, 28 Nov 2010 21:09:51 +0800
[EXPAND] Free IFS state in evalbackcmd
On Sun, Nov 07, 2010 at 04:04:20PM -0600, Jonathan Nieder wrote:
> Herbert Xu wrote:
> > commit f42e443bb511ed3224f09b4fcf0772438ebdbbfa
> > Author: Herbert Xu <herbert@gondor.apana.org.au>
> > Date: Wed Sep 8 20:07:26 2010 +0800
> >
> > [EXPAND] Fix ifsfirst/ifslastp leak
>
> Another puzzle bisecting to f42e443bb. This one comes from the
> grub-mkconfig script:
>
> $ sh -c 'datadir=/usr/share; pkgdatadir=${datadir}/`cat`' 2>&1 | cat -A
> cat: M-^\^M^F^HM-4^M^F^HM-(^M^F^H: No such file or directory$
> cat: M-(^M^F^H: No such file or directory$
>
> Still reproducible with 016b529. I'll try to find time to look into
> it, but thought you might like to know nevertheless.
This is the symptom of another leak. In this case evalbackcmd
occurs in the middle of an expansion (as it should) but the forked
child never clears the previous IFS state.
This patch adds the missing ifsfree call.
This wasn't as much of a problem as the previously discovered leaks
since all it means is that the child gets to carry around the parent's
expansion state and the child is usually short-lived.
Reported-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Fallout 3:
Date: Tue, 15 Mar 2011 16:01:34 +0800
[EXPAND] Free IFS state after here document expansion
Here's another bug bisecting to f42e443bb ([EXPAND] Fix
ifsfirst/ifslastp leak, 2010-09-08). It was found with the following
test case, based on the configure script for Tracker:
dash -x -c '
<<-_ACEOF
$@
_ACEOF
exec
' - abcdefgh
+
+ exec ?a
exec: 1: : Permission denied
The missing ifsfree call is in expandarg when it returns to openhere
during here document expansion.
Reported-by: Aurelien Jarno <aurel32@debian.org>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
ifsfree - 66 +66
ash_main 1490 1495 +5
argstr 1154 1159 +5
evalcase 275 270 -5
expandarg 972 888 -84
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/2 up/down: 76/-89) Total: -13 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit "[EVAL] Force fork if any trap is set, not just on EXIT"
had a similar code as our fix to that bug.
Eliminate some superficial differences.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
There was a bug in tryexec which bbox had fixed in 2003.
dash had a smaller fix in 2007. Copy it. It is smaller,
although it is also more quirky (requires argv[-1] to exist).
Upstream commit 1:
Date: Mon, 15 Oct 2007 20:24:28 +0800
[EXEC] Fixed execing of scripts with no hash-bang
The function tryexec used the original name instead of the path found through
PATH search. This patch fixes that.
Test case:
trap 'rm -f $TMP' EXIT
TMP=$(tempfile -s nosuchthing)
cat <<- EOF > $TMP
echo OK
EOF
chmod u+x $TMP
cd /
PATH=${TMP%/*} ${TMP##*/}
Old result:
/bin/sh: Can't open filelgY4Fanosuchthing
New result:
OK
Upstream commit 2:
Date: Sun, 23 Dec 2007 11:02:26 +0800
[EVAL] Fix bad pointer arithmetic in evalcommand
dash dies on sparc with a SIGBUS due to an arithmetic error introduced
with commit 03b4958, this patch fixes it.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
evalcommand 1261 1264 +3
dotcmd 321 319 -2
tryexec 115 64 -51
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 3/-53) Total: -50 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Mon, 31 Aug 2009 22:06:41 +1000
[CD] Lookup PWD after going through CDPATH
On Tue, Jul 14, 2009 at 09:39:03PM +0000, Eric Blake wrote:
> For the cd command, POSIX 2008 requires that after all pathnames in CDPATH
> have been tested and failed in step 5, then step 6 interprets the directory
> argument relative to PWD. In other words, this demonstrates a bug:
>
> $ dash -c 'cd /tmp; mkdir -p foo; CDPATH=oops; cd foo; echo $?; pwd'
> cd: 1: can't cd to foo
> 2
> /tmp
>
> while bash gets it correct:
>
> $ bash -c 'cd /tmp; mkdir -p foo; CDPATH=oops; cd foo; echo $?; pwd'
> 0
> /tmp/foo
This patch fixes the problem.
Reported-by: Eric Blake <ebb9@byu.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
cdcmd 667 680 +13
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream patch:
Date: Fri, 5 Oct 2007 23:26:45 +0800
[MEMALLOC] Made grabstackblock an inline wrapper for stalloc
The function grabstackblock is identical in semantics to stalloc within its
input constraints.
function old new delta
dotcmd 319 321 +2
grabstackblock 19 5 -14
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sat, 6 Oct 2007 21:18:58 +0800
[VAR] Remove setvarsafe
The only user of setvarsafe is getopts. However, we can achieve the same
result by pre-setting the value of shellparam.optind.
function old new delta
getoptscmd 614 515 -99
setvarsafe 147 - -147
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 0/1 up/down: 0/-246) Total: -246 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 4 Oct 2007 22:20:38 +0800
[PARSER] Size optimisations in parameter expansion parser
Merge flags into subtype.
Do not write subtype out twice.
Add likely flag on ${ vs. $NAME.
Kill unnecessary (and bogus) PEOA check.
function old new delta
readtoken1 2891 2860 -31
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit 1:
Date: Wed, 26 Sep 2007 17:14:16 +0800
[PARSER] Recognise here-doc delimiters terminated by EOF
Previously dash required a <newline> character to be present in order for
a here-document delimiter to be detected. Allowing EOF in the absence of
a <newline> to play the same purpose allows some intuitive scripts to
succeed. POSIX seems to be silence on this so this should be OK.
Test case:
eval 'cat <<- NOT
test
NOT'
echo OK
Old result:
test
NOTOK
New result:
test
OK
Upstream commit 2:
Date: Sat, 20 Oct 2007 18:49:31 +0800
[PARSER] Fix here-doc corruption
The change
[PARSER] Recognise here-doc delimiters terminated by EOF
introduced a regerssion whereby lines starting with eofmark but are not equal
to eofmark would be corrupted. This patch fixes it.
Test case:
cat << _ACEOF
_ASBOX
_ACEOF
Old result:
SASBOX
New result:
_ASBOX
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 4 Oct 2007 22:15:10 +0800
[PARSER] Fix parsing of ${##1}
Previously dash treated ${##1} as a length operation. This patch fixes that.
Test case:
set -- a
echo ${##1}OK
Old result:
1OK
New result:
OK
This was a real bug in ash (but not in hush).
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sun, 6 May 2007 19:28:56 +1000
[REDIR] Remove redundant CLOEXEC calls
Now that we're marking file descriptors as CLOEXEC in savefd, we no longer
need to close them on exec or in setinputfd.
function old new delta
ash_main 1478 1492 +14
setinputfile 224 226 +2
readtoken1 2752 2750 -2
shellexec 208 198 -10
clearredir 30 - -30
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/2 up/down: 16/-42) Total: -26 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sat, 12 May 2007 18:00:57 +1000
[REDIR] Replace copyfd by savefd and use dup2 elsewhere
There are two kinds of users to copyfd, those that want to copy an fd to
an exact value and those that want to move an fd to a value >= 10. The
former can simply use dup2 directly while the latter share a lot of common
code that now constitutes savefd.
This does not change much, just reducing our divergence from dash code.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sat, 6 Oct 2007 18:59:31 +0800
[BUILTIN] Treat OPTIND=0 in the same way as OPTIND=1
Previously setting OPTIND to 0 would cause subsequent getopts calls to fail.
This patch makes dash reset the getopts parameters the same way as OPTIND=1.
Both behaviours are allowed by POSIX but other common shells do tolerate this
case.
function old new delta
getoptsreset 24 30 +6
getoptscmd 632 614 -18
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstreams commit:
Date: Mon, 8 Oct 2007 21:32:25 +0800
[PARSER] Report substition errors at expansion time
On Wed, Apr 11, 2007 at 01:24:21PM -0700, Micah Cowan wrote:
> This operation fails on Ubuntu:
>
> $ /bin/sh -c 'if false; then d="${foo/bar}"; fi'
> /bin/sh: Syntax error: Bad substitution
>
> When used with other POSIX shells it succeeds. While semantically the
> variable reference ${foo/bar} is not valid, this is not a syntax error
> according to POSIX, and since the variable assignment expression is
> never invoked (because it's within an "if false") it should not be seen
> as an error.
>
> I ran into this because after restarting my system I could no longer log
> in. It turns out that the problem was (a) I had edited .gnomerc to
> source my .bashrc file so that my environment would be set properly, and
> (b) I had added some new code to my .bashrc WITHIN A CHECK FOR BASH!
> that used bash's ${var/match/sub} feature. Even though this code was
> within a "case $BASH_VERSION; in *[0-9]*) ... esac (so dash would never
> execute it since that variable is not set), it still caused dash to
> throw up.
>
> FYI, some relevant details from POSIX:
>
> Section 2.3, Token Recognition:
>
> 5. If the current character is an unquoted '$' or '`', the shell shall
> identify the start of any candidates for parameter expansion ( Parameter
> Expansion), command substitution ( Command Substitution), or arithmetic
> expansion ( Arithmetic Expansion) from their introductory unquoted
> character sequences: '$' or "${", "$(" or '`', and "$((", respectively.
> The shell shall read sufficient input to determine the end of the unit
> to be expanded (as explained in the cited sections).
>
> Section 2.6.2, Parameter Expansion:
>
> The format for parameter expansion is as follows:
>
> ${expression}
>
> where expression consists of all characters until the matching '}'. Any
> '}' escaped by a backslash or within a quoted string, and characters in
> embedded arithmetic expansions, command substitutions, and variable
> expansions, shall not be examined in determining the matching '}'.
> [...]
>
> 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 followed by a character that could be interpreted as
> part of the name. The matching closing brace shall be determined by
> counting brace levels, skipping over enclosed quoted strings, and
> command substitutions.
> ---
> In addition to bash I've checked Solaris /bin/sh and ksh and they don't
> report an error.
>
> -----
> Micah Cowan:
>
> The applicable portion of POSIX is in XCU 2.10.1:
>
> "The WORD tokens shall have the word expansion rules applied to them
> immediately before the associated command is executed, not at the time
> the command is parsed."
>
> This seems fairly clear to me.
This patch moves the error detection to expansion time.
Test case:
if false; then
echo ${a!7}
fi
echo OK
Old result:
dash: Syntax error: Bad substitution
New result:
OK
function old new delta
evalvar 574 585 +11
readtoken1 2763 2750 -13
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 27 May 2010 14:21:17 +0800
[REDIR] Move null redirect checks into caller
The null redirect checks were added as an optimisation to avoid
unnecessary memory allocations. However, we could avoid this
completely by simply making the caller avoid making a redirection
unless it is not null.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
evaltree 784 809 +25
evalcommand 1251 1261 +10
hashvar 59 62 +3
dotcmd 321 319 -2
clearredir 37 30 -7
popredir 183 162 -21
redirect 1264 1233 -31
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/4 up/down: 63/-61) Total: -23 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream patch:
Date: Thu, 27 Dec 2007 13:57:07 +1100
[PARSER] Do not show prompts in expandstr
Once I fixed the previous problem it became apparent that we never dealt
with prompts with new-lines in them correctly. The problem is that we
showed a secondary prompt for each of them.
This patch disables prompt generation in expandstr.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
expandstr 102 127 +25
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sun, 11 Nov 2007 15:00:06 +0800
[EXPAND] Removed herefd hack
The herefd hack goes back more than a decade. it limits the amount of
memory we have to allocate when expanding here-documents by writing the
result out from time to time. However, it's no longer safe because the
stack is used to place intermediate results too and there we certainly
don't want to write them out should we be short on memory.
In any case, with today's computers we can afford to keep the entire
result in memory and write them out at the end.
function old new delta
redirect 1268 1264 -4
ash_main 1485 1478 -7
subevalvar 1157 1132 -25
growstackstr 54 24 -30
argstr 1192 1154 -38
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/5 up/down: 0/-104) Total: -104 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
We need to flush at the very end in case we've generated any errors
before that. The flushall call cannot perform a longjmp so it's
safe there.
Date: Sat, 22 Sep 2007 20:50:21 +0800
[SHELL] Move flushall to the point just before _exit
We need to flush at the very end in case we've generated any errors
before that. The flushall call cannot perform a longjmp so it's
safe there.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream patch:
Date: Tue, 15 Mar 2011 15:44:47 +0800
[EVAL] Let funcnode refer to a function definition, not its first command
It is not unrelated: I changed the meaning of struct funcnode's field n
to refer to the function definition, rather than the list of the
function's commands, because I needed to refer to the function
definition node from evalfun, which only gets passed a funcnode. But it
is something that could be applied independently (without being useful
by itself), so I've attached it as a separate patch for easier review.
Signed-off-by: Harald van Dijk <harald@gigawatt.nl>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sun, 6 May 2007 12:01:37 +1000
[REDIR] Remove EMFILE special case
No caller of copyfd need to ignore EMFILE so we can remove the special
case and just let it call sh_error on any error.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Tue, 6 Jul 2010 17:50:37 +0800
[PATCH 161/277] [EVAL] Check exit for eval NSUBSHELL
Example:
$ dash -c 'set -e; (false); echo here'
here
With this commit, dash exits 1 before echo.
The bug was reported by Stefan Fritsch through
http://bugs.debian.org/514863
Signed-off-by: Gerrit Pape <pape@smarden.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This was fixed differently in our tree:
Date: Fri Sep 16 19:04:02 2016 +0000
ash: exit after subshell error when errexit option is set
When "set -e" option is on, shell must exit when any command fails,
including compound commands of the form (compound-list) executed in a
subshell. Bash and dash shells have this behaviour.
Also add a corresponding testcase.
Signed-off-by: Rostislav Skudnov <rostislav@tuxera.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Wed, 8 Sep 2010 16:21:52 +0800
[JOBS] Debug compile fix
No point in tracing a no longer undeclared "ps->cmd", fixes:
jobs.c: In function \u2018commandtext\u2019:
jobs.c:1192: error: \u2018ps\u2019 undeclared (first use in this function)
jobs.c:1192: error: (Each undeclared identifier is reported only once
jobs.c:1192: error: for each function it appears in.)
Signed-off-by: maximilian attems <max@stro.at>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sun, 28 Nov 2010 20:47:07 +0800
[BUILTIN] Stop documenting EXSHELLPROC
At some point between ash 0.3.5-11.0.1 and ash 0.3.8-37, Debian
ash stopped using the EXSHELLPROC exception to handle shell
scripts without a magic number.
Remove all remaining references to it to avoid confusion.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Sun, 28 Nov 2010 20:44:37 +0800
[BUILTIN] Use EXEXIT in place of EXEXEC
The intended semantics of EXEXEC are identical to EXEXIT, so
simplify by using EXEXIT directly.
Functional change: in edge cases (exec within a trap handler),
this causes the exit status from exec not to be clobbered.
For example, without this patch:
$ sh -c 'trap "exec nonexistent" EXIT'; echo $?
exec: 1: nonexistent: not found
0
And with it:
$ sh -c 'trap "exec nonexistent" EXIT'; echo $?
exec: 1: nonexistent: not found
127
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit 1 for ash:
[ERROR] Allow the originator of EXERROR to set the exit status
Some errors have exit status values specified by POSIX and it is
therefore desirable to be able to set the exit status at the EXERROR
source rather than in main.c.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Upstream commit 2 for ash:
[INPUT] Use exit status 127 when the script to run does not exist
This commit makes dash exit with return code 127 instead of 2 if
started as non-interactive shell with a non-existent command_file
specified as argument (or a directory), as documented in
http://www.opengroup.org/onlinepubs/009695399/utilities/sh.html#tag_04_128_14
The wrong exit code was reported by Clint Adams and Jari Aalto through
http://bugs.debian.org/548743http://bugs.debian.org/548687
Signed-off-by: Gerrit Pape <pape@smarden.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
NB: in fact, http://bugs.debian.org/548687 was not fixed by this:
"sh /dir/" thinks that EISDIR error on read is EOF, and exits 0.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The commit 'ash: eval: Return status in eval functions' changed how
exit status is handled in eval functions. The case of nofork
applets was missed, resulting in the incorrect status potentially
being returned for nofork applets when FEATURE_SH_NOFORK is enabled.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Previous commit probably introduced a bug:
non-matching size calculation in size counting and
actual copying caused by SHELL_ALIGN being applied differently!
This won't bite if string sizes are also SHELL_ALIGNed.
Thus fixing.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
dash has tokendlist[] array to decide which tokens end lists.
We store it as first byte of each tokname_array[i].
Switch to bit array, name it like dash (tokendlist), drop special
1st byte of tokname_array[i]. This brings us closer to dash, and
shrinks the binary, because many more string aliasing opportunities
are now open:
function old new delta
pstrcmp1 - 16 +16
readtoken1 2852 2858 +6
list 326 327 +1
pstrcmp 16 15 -1
tokname 45 42 -3
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/2 up/down: 23/-4) Total: 19 bytes
text data bss dec hex filename
943556 916 14292 958764 ea12c busybox_old
943463 916 14292 958671 ea0cf busybox_unstripped
^^^^^^^ note this!
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Upstream commit:
Date: Thu, 1 Jan 2015 07:53:10 +1100
expand: Fixed "$@" expansion when EXP_FULL is false
The commit 3c06acdac0b1ba0e0acdda513a57ee6e31385dce ([EXPAND]
Split unquoted $@/$* correctly when IFS is set but empty) broke
the case where $@ is in quotes and EXP_FULL is false.
In that case we should still emit IFS as field splitting is not
performed.
Reported-by: Juergen Daubert <jue@jue.li>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>