Commit Graph

744 Commits

Author SHA1 Message Date
Denys Vlasenko
48c803a206 ash: fix $HOME/.profile reading if !ASH_EXPAND_PRMT, take 2
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-01 23:26:12 +02:00
Denys Vlasenko
e9aba3e7ea ash: fix 'trap - 65'
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-01 21:09:27 +02:00
Denys Vlasenko
f56ddf2e4c ash: fix $HOME/.profile reading if !ASH_EXPAND_PRMT
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-06-27 17:51:07 +02:00
Youfu Zhang
6683d1cbb4 ash: fix incorrect path in describe_command
$ 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>
2017-05-26 17:37:35 +02:00
Denys Vlasenko
f547041940 ash,hush: fix SIGCHLD interrupting read builtin
function                                             old     new   delta
readcmd                                              169     217     +48
shell_builtin_read                                  1087    1097     +10
localcmd                                             366     364      -2
builtin_read                                         197     193      -4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/2 up/down: 58/-6)              Total: 52 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-05-22 19:34:45 +02:00
Denys Vlasenko
10ad622dc2 Spelling fixes in comments, documentation, tests and examples
By klemens <ka7@github.com>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-04-17 16:13:32 +02:00
Denys Vlasenko
6c149f4d9a ash: implement "exec -a ARGV0 CMD ARGV1..."
function                                             old     new   delta
execcmd                                               71     112     +41
shellexec                                            221     224      +3
evalcommand                                         1158    1161      +3
localcmd                                             364     366      +2
unaliascmd                                           163     154      -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 49/-9)              Total: 40 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-04-12 21:31:32 +02:00
Denys Vlasenko
e139ae307e ash: make shellexec capable of using separate argv[0] and filename to exec
function                                             old     new   delta
execcmd                                               71      78      +7
shellexec                                            221     224      +3
evalcommand                                         1158    1161      +3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 13/0)               Total: 13 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-04-12 21:02:33 +02:00
Denys Vlasenko
5f7c82b32f ash: add INT_OFF/ON around allocations
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-02-03 13:00:06 +01:00
Felix Fietkau
b5b21126ca ash: improve / fix glob expansion
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>
2017-01-31 21:58:55 +01:00
Denys Vlasenko
205d48e948 *: add comment about APPLET_ODDNAME format
It confused me more than once

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-01-29 14:57:33 +01:00
Denys Vlasenko
098b713c7b ash: commented-out possible fix for 7694
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>
2017-01-11 19:59:03 +01:00
Denys Vlasenko
4c179373e0 ash: 16-bit ->nprocs field is a pain for many CPUs
function                                             old     new   delta
getoptscmd                                           527     540     +13
getjob                                               280     286      +6
makejob                                              278     282      +4
forkchild                                            602     600      -2
waitcmd                                              208     205      -3
showjob                                              382     379      -3
getstatus                                             83      80      -3
dowait                                               408     405      -3
freejob                                               93      89      -4
fg_bgcmd                                             290     286      -4
forkshell                                            260     255      -5
killcmd                                              224     218      -6
jobno                                                 17      11      -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/10 up/down: 23/-39)           Total: -16 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-01-11 18:44:15 +01:00
Denys Vlasenko
7d4aec0c3e ash: split bash compatible extensions into separate defines. No code changes
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>
2017-01-11 14:00:38 +01:00
Denys Vlasenko
2b4c258e74 ash: revert "make dot command search current directory first"
Reverts this:
    commit 8ad78e1ec7
    Author: Denis Vlasenko <vda.linux@googlemail.com>
    Date:   Sun Feb 15 12:40:30 2009 +0000
    ash: make dot command search current directory first, as bash does.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-01-10 15:18:38 +01:00
Denys Vlasenko
265062d59d shells: make hush test optional, rename ASH_BUILTIN_foo -> ASH_foo
This makes hash and ash more symmetrical wrt config menu and config
options.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-01-10 15:13:30 +01:00
Denys Vlasenko
f560422fa0 Big cleanup in config help and description
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>
2017-01-10 14:58:54 +01:00
Denys Vlasenko
fb87d93d1e ash: fix a bug in argv restoration after sourcing a file
if sourced file "shift"ed argvs so that $1 is NULL, restore wasn't done.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-01-09 08:22:06 +01:00
Denys Vlasenko
86584e134e ash: fix open fds leaking in redirects. Closes 9561
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>
2017-01-07 10:16:56 +01:00
Kang-Che Sung
6cd0294725 ash: explicltly group ash options
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>
2017-01-06 17:03:18 +01:00
Ron Yorston
ea7d2f6ec0 ash: fix error code regression
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>
2017-01-03 11:18:23 +01:00
Denys Vlasenko
0b8835861b Make it possible to select "sh" and "bash" aliases without selecting ash or hush
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>
2016-12-23 16:56:43 +01:00
Denys Vlasenko
6704746c69 shell: move "config" blocks above their use in coditional includes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-12-22 15:21:58 +01:00
Denys Vlasenko
326edc3e37 Tweak some config defaults; fix MODPROBE_SMALL ordering in "make config"
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-12-22 14:36:49 +01:00
Denys Vlasenko
2166952ec3 ash: clarify uclibc glob() bug in comment
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-12-21 21:04:16 +01:00
Denys Vlasenko
3a4cdf45f9 ash: error out if ASH_INTERNAL_GLOB is not selected on uClibc
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-12-21 04:13:23 +01:00
Denys Vlasenko
2fe66b1d2d ash: fix signed char expansion bug
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-12-12 17:39:12 +01:00
Denys Vlasenko
b6afcc7819 shell: suppress "unused var/func" warnings on some configs
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-12-12 16:30:20 +01:00
Denys Vlasenko
4b89d512b1 ash,hush: make ^C in interactive mode visually much closer to bash behavior
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-11-25 03:41:03 +01:00
Denys Vlasenko
8660aeb312 ash,hush: ^C from command line should set $? to 128+SIGINT
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-11-24 17:44:02 +01:00
Denys Vlasenko
15fb91cefb test: make [ and [[ forms individually selectable
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-11-23 18:31:48 +01:00
Denys Vlasenko
06b114900f ash: fix "duplicate local" code (forgot to re-enable interrupts)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-11-04 16:43:18 +01:00
Denys Vlasenko
1ab7c2fc6d ash: while (!got_sig) pause() is not reliable, use sigsuspend()
dash was doing it for a reason. Unfortunately, it had no comment why...
now I know.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-11-03 20:22:54 +01:00
Denys Vlasenko
d4f3db9427 ash: if using libc glob(), skip it if no metachars are in word
This saves making tons of pointless stat() calls

function                                             old     new   delta
expandarg                                            888     921     +33

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-30 18:41:01 +01:00
Denys Vlasenko
474ed06c39 ash: fix bit-rotten debug infrastructure
DEBUG = 2 output was a bit messed up

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-30 18:30:29 +01:00
Denys Vlasenko
493b9cae80 ash: make popfile() anfter popallfiles() safe
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>
2016-10-30 18:27:14 +01:00
Denys Vlasenko
8f7b0248ad ash: use pause(), not sigsuspend(), in wait builtin
Same effect, smaller code

function                                             old     new   delta
dowait                                               463     374     -89

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-28 17:16:11 +02:00
Denys Vlasenko
d81e9f5093 ash: fix interactive "command eval STRING" exiting on errors.
This bug is also present in current dash

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-28 15:43:50 +02:00
Denys Vlasenko
458c1f218b ash: [JOBS] Fix dowait signal race
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>
2016-10-27 23:51:19 +02:00
Denys Vlasenko
c0663c7cd2 ash: [SIGNAL] Remove EXSIG
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>
2016-10-27 21:13:49 +02:00
Denys Vlasenko
6918811014 ash: open-code blocking_dowait_with_raise_on_sig()
There is in fact only one callsite.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-27 21:13:24 +02:00
Denys Vlasenko
b543bdadb3 ash: return to DOWAIT_* constants similar to dash, no logic changes
This loses an insignificant optimization, but may allow backporting
of some recent-ish dash fixes.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-27 21:13:24 +02:00
Denys Vlasenko
3f44a6be58 ash: delete leftovers from "simplify EOF/newline handling in list parser" commit
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>
2016-10-27 14:49:21 +02:00
Denys Vlasenko
5ac04f2f02 ash: [EXPAND] Fix ifsfirst/ifslastp leak
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>
2016-10-27 14:46:50 +02:00
Denys Vlasenko
455e422814 ash: move ifsbreakup() and ifsfree() up
Preparatory patch.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-27 14:46:17 +02:00
Denys Vlasenko
b4f51d32d2 ash: partially sync with dash on "fork if traps are set" logic
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>
2016-10-27 12:55:09 +02:00
Denys Vlasenko
2eb0a7e1b9 ash: [SHELL] Expand ENV before using it
Upstream commit:

    Date: Sun, 13 Jul 2008 21:51:52 +0800
    [SHELL] Expand ENV before using it

    Per POSIX ENV needs to undergo parameter expansion.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-27 11:28:59 +02:00
Denys Vlasenko
70392331a9 ash: comment tweaks, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-27 02:31:55 +02:00
Denys Vlasenko
65a8b859a9 ash: optimize tryexec(): avoid one allocation
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>
2016-10-26 22:29:11 +02:00
Denys Vlasenko
0e081d01a8 ash: [CD] Lookup PWD after going through CDPATH
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>
2016-10-26 19:56:05 +02:00
Denys Vlasenko
a318bba199 ash: [MEMALLOC] Made grabstackblock an inline wrapper for stalloc
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>
2016-10-26 18:26:27 +02:00
Denys Vlasenko
dbef38a74b ash: [VAR] Remove setvarsafe
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>
2016-10-26 17:54:32 +02:00
Denys Vlasenko
35c2a136cd ash: use shellparam.optind/optoff in getopts() directly, not through pointers
This is a preparatory patch for next change

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-26 17:34:26 +02:00
Denys Vlasenko
3df1410a00 ash: [PARSER] Size optimisations in parameter expansion parser
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>
2016-10-26 16:41:13 +02:00
Denys Vlasenko
350e686f3b ash: [PARSER] Recognise here-doc delimiters terminated by EOF
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>
2016-10-26 16:26:45 +02:00
Denys Vlasenko
f15aa57a7f ash: [PARSER] Fix parsing of ${##1}
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>
2016-10-26 15:56:53 +02:00
Denys Vlasenko
e19923f665 ash: [REDIR] Remove redundant CLOEXEC calls
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>
2016-10-26 15:38:44 +02:00
Denys Vlasenko
647746076a ash: [REDIR] Replace copyfd by savefd and use dup2 elsewhere
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>
2016-10-26 15:24:30 +02:00
Denys Vlasenko
a513bf3c3c ash: [BUILTIN] Treat OPTIND=0 in the same way as OPTIND=1
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>
2016-10-26 02:03:37 +02:00
Denys Vlasenko
88e15703ac ash: [PARSER] Report substition errors at expansion time
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>
2016-10-26 01:55:56 +02:00
Denys Vlasenko
eaf9436b08 ash: [REDIR] Move null redirect checks into caller
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>
2016-10-25 21:46:03 +02:00
Denys Vlasenko
2a6d29ad5c ash: [PARSER] Do not show prompts in expandstr
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>
2016-10-25 21:17:52 +02:00
Denys Vlasenko
579ad107a6 ash: [EXPAND] Removed herefd hack
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>
2016-10-25 21:10:20 +02:00
Denys Vlasenko
caee80cd3d ash: [SHELL] Move flushall to the point just before _exit
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>
2016-10-25 20:49:53 +02:00
Denys Vlasenko
7aec86820d ash: [EVAL] Let funcnode refer to a function definition, not its first command
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>
2016-10-25 20:26:02 +02:00
Denys Vlasenko
20a2cd6291 ash: [REDIR] Remove EMFILE special case
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>
2016-10-25 19:04:39 +02:00
Denys Vlasenko
cf98b0c085 ash: [EVAL] Check exit for eval NSUBSHELL
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>
2016-10-25 18:19:39 +02:00
Denys Vlasenko
960ca385b7 ash: add comment explaining "set -e; $(cmd)" discrepancy
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-25 18:12:15 +02:00
Denys Vlasenko
6a94cee409 ash: reduce code differences from upstream
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>
2016-10-25 17:41:06 +02:00
Denys Vlasenko
1825e4f935 ash: remove unused EXSHELLPROC
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>
2016-10-25 17:26:56 +02:00
Denys Vlasenko
061a09091f ash: [BUILTIN] Use EXEXIT in place of EXEXEC
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>
2016-10-25 17:24:25 +02:00
Denys Vlasenko
b7adf7ac32 ash,hush: set exit code 127 in "sh /does/not/exist" case
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/548743
     http://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>
2016-10-25 17:00:13 +02:00
Denys Vlasenko
db74c6caed ash: explain EXP_REDIR and why we (dont) glob redir filenames
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-24 21:12:33 +02:00
Ron Yorston
5ccb0e92fa ash: return exit status of nofork applets
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>
2016-10-24 01:18:13 +02:00
Denys Vlasenko
561639a68c ash: all blocks in function node copying must be SHELL_ALIGNed
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>
2016-10-07 04:28:33 +02:00
Denys Vlasenko
4c438b5ba4 ash: get rid of two global data variables
function                                             old     new   delta
calcsize                                             126     147     +21
funcstring_end                                         -       4      +4
sizenodelist                                          28      24      -4
funcstringsize                                         4       -      -4
funcstring                                             4       -      -4
funcblocksize                                          4       -      -4
nodeckstrdup                                          48      39      -9
evaltree                                             828     788     -40
------------------------------------------------------------------------------
(add/remove: 1/3 grow/shrink: 1/4 up/down: 25/-105)           Total: -40 bytes
   text	   data	    bss	    dec	    hex	filename
 943376	    916	  14292	 958584	  ea078	busybox_old
 943344	    916	  14284	 958544	  ea050	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-07 04:05:15 +02:00
Denys Vlasenko
f37e1155aa ash: comment out free(p) just before _exit, tweak some outdated comments
Planned to sync exitshell up to dash, turned out ours is better :)

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-07 03:17:28 +02:00
Denys Vlasenko
ce332a23a3 ash: [PARSER] Add nlprompt/nlnoprompt helpers
Upstream commit:

    Date: Mon, 29 Sep 2014 22:53:53 +0800
    [PARSER] Add nlprompt/nlnoprompt helpers

    This patch adds the nlprompt/nlnoprompt helpers to isolate code
    dealing with newlines and prompting.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-02 23:47:34 +02:00
Denys Vlasenko
80729a4472 whitespace fixes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-02 22:33:15 +02:00
Denys Vlasenko
ebedb9478d sh: do not print empty line at the end of "help" output
It's pointless.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-02 18:45:09 +02:00
Denys Vlasenko
888527ccee ash: undo "tokname hack"
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>
2016-10-02 16:54:17 +02:00
Denys Vlasenko
bc1a00843f ash: placate gcc: "warning: ! is only applied to the left hand side of =="
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-02 15:31:33 +02:00
Denys Vlasenko
8e2c9cc2fc ash: fix globbing bugs when using glibc glob()
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-02 15:17:15 +02:00
Denys Vlasenko
37dc08b874 ash: style fixes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-02 04:38:07 +02:00
Denys Vlasenko
0cdb7ea380 ash: support "--" in "source" builtin
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-02 03:16:00 +02:00
Denys Vlasenko
0aaaa50b45 ash: expand: Fixed "$@" expansion when EXP_FULL is false
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>
2016-10-02 02:46:56 +02:00
Denys Vlasenko
de89205bdf test: memory leak: free group id list
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-02 01:49:13 +02:00
Denys Vlasenko
b98b4c103f ash: fix return_in_trap1.tests failure
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 23:25:12 +02:00
Denys Vlasenko
0dd8e45d42 ash: [EXPAND] Optimise nulonly away and just use quoted as before
Upstream commit:

    Date: Wed, 8 Oct 2014 20:09:56 +0800
    [EXPAND] Optimise nulonly away and just use quoted as before

    This patch makes a small optimisation by using the same value for
    quoted between evalvar and varvalue by eliminating nulonly and
    passing along quoted instead.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 21:02:06 +02:00
Denys Vlasenko
88ac97d02d ash: [EXPAND] Do not split quoted VSLENGTH and VSTRIM
Upstream patch:

    Date: Wed, 8 Oct 2014 15:42:08 +0800
    [EXPAND] Do not split quoted VSLENGTH and VSTRIM

    Currently VSLENGTH and VSTRIM* are field-split even within quotes.
    This is obviously wrong.  This patch fixes that.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 20:55:02 +02:00
Denys Vlasenko
c4d4380a07 ash: [EXPAND] Split unquoted $@/$* correctly when IFS is set but empty
Upstream commit:

    Date: Wed, 8 Oct 2014 15:24:23 +0800
    [EXPAND] Split unquoted $@/$* correctly when IFS is set but empty

    Currently we do not field-split $@/$* when it isn't quoted and IFS
    is set but empty.  This is obviously wrong.  This patch fixes this.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 20:35:10 +02:00
Denys Vlasenko
35ec818fa2 ash: fix "return N" not setting $? in loop conditionals
Upstream commit 1:

    Date: Mon, 6 Oct 2014 20:45:04 +0800
    [EVAL] Move common skipcount logic into skiploop

    The functions evalloop and evalfor share the logic on checking
    and updating skipcount.  This patch moves that into the helper
    function skiploop.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Upstream commit 2:

    Date: Mon, 6 Oct 2014 21:22:43 +0800
    [BUILTIN] Allow return in loop conditional to set exit status

    https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=332954

    When return is used in a loop conditional the exit status will
    be lost because we always set the exit status at the end of the
    loop to that of the last command executed in the body.

    This is counterintuitive and contrary to what most other shells do.

    This patch fixes this by always preserving the exit status of
    return when it is used in a loop conditional.

    The patch was originally written by Gerrit Pape <pape@smarden.org>.

    Reported-by: Stephane Chazelas <stephane_chazelas@yahoo.fr>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 19:56:52 +02:00
Denys Vlasenko
4d12e944ea ash: [ERROR] Set exitstatus in onint
Partially backported this commit:

    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>

The part after "if (evalbltin(cmdentry.u.cmd, argc, argv, flags))"
causes testsuite failures in signal handling, so left unchanged.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 16:03:11 +02:00
Denys Vlasenko
0840c91909 ash: [EVAL] Revert SKIPEVAL into EXEXIT
Upstream commit:

    Date:   Tue Aug 11 20:56:53 2009 +1000
    [EVAL] Revert SKIPEVAL into EXEXIT

    Now that eval handles EV_TESTED correctly, we can remove the
    SKIPEVAL hack and simply use EXEXIT for set -e.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 15:27:44 +02:00
Denys Vlasenko
7b3fa1e441 ash: [EVAL] Pass EV_TESTED into evalcmd
Upstream commit:

    Date:   Tue Aug 11 20:48:15 2009 +1000
    [EVAL] Pass EV_TESTED into evalcmd

    This patch fixes the case where the eval command is used with
    set -e and as part of a construct that should not cause the
    shell to abort, e.g., as part of the condition of an if statement.

    This is achieved by propagating the EV_TESTED flag into the
    evalstring function through evalcmd.  As this alters the prototype
    of evalcmd it is now invoked explicitly by evalbltin.  The built-in
    infrastructure has been changed to accomodate this special case.

    In order to ensure that the EXIT trap is properly executed this
    patch clears evalskip in exitshell.  This wasn't needed before
    because of the broken way evalstring worked where it always clears
    evalskip when called by minusc.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Although, I failed to create a reproducer for this.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 15:10:16 +02:00
Denys Vlasenko
08089c7c85 ash: fix a thinko in the last commit
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 14:47:52 +02:00
Denys Vlasenko
514b51ddf3 ash: make internal globbing code selectable from config
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 14:33:08 +02:00
Denys Vlasenko
cac4d002e7 ash: explain how "command" is handled, and shrink it a bit
function                                             old     new   delta
getoptscmd                                           641     632      -9
commandcmd                                            79      69     -10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-19)             Total: -19 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 03:02:25 +02:00
Denys Vlasenko
e627ac95be ash: [VAR] Initialise OPTIND after importing environment
Upstream commit 1:

    Date: Fri, 23 Aug 2013 21:27:42 +1000
    [VAR] Initialise OPTIND after importing environment

    On Sat, Mar 23, 2013 at 01:46:20AM +0000, Chris F.A. Johnson wrote:
    >   According to both the dash man page and the POSIX spec, "When the
    >   shell is invoked, OPTIND is initialized to 1."
    >
    >   However, it actually takes the value of the environment variable
    >   if it exists:
    >
    > $ OPTIND=4 dash -c 'echo "$OPTIND"'
    > 4
    > $ OPTIND=4 bash -c 'echo "$OPTIND"'
    > 1
    > $ OPTIND=4 ksh -c 'echo "$OPTIND"'
    > 1
    > $ OPTIND=4 ksh93 -c 'echo "$OPTIND"'
    > 1

    This patch fixes this by initialising OPTIND after importing the
    environment.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Upstream commit 2:

    Date: Tue, 7 Oct 2014 22:24:42 +0800
    [VAR] Use setvareq to set OPTIND initially

    There is no need to setvarint to set the initial value of OPTIND
    of one.  This patch switchs to setvareq which also lets us avoid
    an unnecessary memory allocation.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 14:46:41 +02:00
Denys Vlasenko
6a0710e954 ash: [BUILTIN] Merge SKIPFUNC/SKIPFILE and only clear SKIPFUNC when leaving dotcmd
Upstream commit:

    Date: Sat, 9 Jul 2011 22:05:22 +0800
    [BUILTIN] Merge SKIPFUNC/SKIPFILE and only clear SKIPFUNC when leaving dotcmd

    Currently upon leaving a dotcmd the evalskip state is reset so
    if a continue/break statement is used within a dot script it would
    have no effect outside of the dot script.

    This is inconsistent with other shells.

    This patch is based on one by Jilles Tjoelker and only clears
    SKIPFUNC when leaving a dot script.  As a result continue/break
    will remain in effect.

    It also merges SKIPFUNC/SKIPFILE as they have no practical difference.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 14:46:41 +02:00