Commit graph

1023 commits

Author SHA1 Message Date
Denys Vlasenko
b668e52c90 *: placate warnings where strchr/strstr returns constant pointer
Newer glibc is now smarter and can propagate const-ness from those!

function                                             old     new   delta
readtoken1                                          3111    3108      -3

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-02-15 15:15:30 +01:00
Denys Vlasenko
9693daaaef *: use is_prefixed_with() where appropriate
function                                             old     new   delta
resume_main                                          560     556      -4
uuidcache_check_device                               107     101      -6
ntp_init                                            1005     997      -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-18)             Total: -18 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-02-07 01:10:55 +01:00
Denys Vlasenko
03d6d1014a ash: fix \ooo octal printout in DEBUG code
function                                             old     new   delta
ash_main                                            1624    1645     +21

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-28 15:12:43 +01:00
Denys Vlasenko
56143ea63f ash: code shrink: eliminate pstrcmp1()
function                                             old     new   delta
find_command                                         961     963      +2
evalcommand                                         1631    1633      +2
hashcmd                                              299     300      +1
describe_command                                     320     321      +1
clearcmdentry                                         93      94      +1
cdcmd                                                695     696      +1
pstrcmp1                                              16       -     -16
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 6/0 up/down: 8/-16)              Total: -8 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-28 09:23:54 +01:00
Denys Vlasenko
758c948a63 ash: remove non-standard chdir builtin
function                                             old     new   delta
.rodata                                           106853  106846      -7
builtintab                                           352     344      -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-15)             Total: -15 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-28 01:34:13 +01:00
Denys Vlasenko
77d242d7ac ash: get rid of a static in cmdlookup()/delete_cmd_entry()
function                                             old     new   delta
cmdlookup_pp                                           -     120    +120
find_command                                         953     961      +8
unsetcmd                                              74      76      +2
hashcmd                                              297     299      +2
lastcmdentry                                           4       -      -4
delete_cmd_entry                                      47      43      -4
cmdlookup                                            132       -    -132
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 3/1 up/down: 132/-140)           Total: -8 bytes
   text	   data	    bss	    dec	    hex	filename
  47470	      8	    149	  47627	   ba0b	shell/ash.o.orig
  47466	      8	    145	  47619	   ba03	shell/ash.o

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-28 01:01:15 +01:00
Denys Vlasenko
2051c69358 ash: group command hashing/searching code together, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-28 00:34:22 +01:00
Denys Vlasenko
e05b922c89 ash: move casematch() directly to its only caller, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-27 23:44:06 +01:00
Denys Vlasenko
c9af9073b8 ash: reorder functions to reduce forward declarations, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-27 17:08:12 +01:00
Denys Vlasenko
b715e82e1f ash: JOBSTOPPED can only be set if job control is compiled in - conditionalize code which depends on it
With !ASH_JOB_CONTROL:

function                                             old     new   delta
cmdloop                                              363     351     -12
exitcmd                                               47      31     -16
.rodata                                           106422  106398     -24
stoppedjobs                                           58       -     -58
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 0/3 up/down: 0/-110)           Total: -110 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-27 13:15:14 +01:00
Denys Vlasenko
dee0168219 ash: reorder functions to reduce forward declarations, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-27 13:15:13 +01:00
Denys Vlasenko
97a7813971 ash: move applet handling out of tryexec() - making it similar to dash
function                                             old     new   delta
tryexec                                                -      60     +60
shellexec                                            476     349    -127
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/1 up/down: 60/-127)           Total: -67 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-27 11:17:38 +01:00
Denys Vlasenko
22b96c0ddf ash: unset traps before entering NOEXEC programs after [v]fork
If we don't do that, if INT trap was set, ^C will set a flag
"run trap later" and _return_, which is not expected by the NOFORK!

function                                             old     new   delta
clear_traps                                            -     107    +107
evalcommand                                         1617    1631     +14
shellexec                                            471     476      +5
setsignal                                            333     327      -6
forkchild                                            620     480    -140
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/2 up/down: 126/-146)          Total: -20 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-27 08:03:15 +01:00
Denys Vlasenko
1db8aa2b59 ash: code shrink
function                                             old     new   delta
fg_bgcmd                                             294     296      +2
killpg                                                43       -     -43
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 1/0 up/down: 2/-43)             Total: -41 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-01-24 23:14:33 +01:00
Denys Vlasenko
381a40a049 ash: change procargs() to match recent dash change
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-09-23 04:46:49 +02:00
Denys Vlasenko
106546961d ash: implement <<<here_string syntax
function                                             old     new   delta
write2pipe                                             -     133    +133
.rodata                                           105992  106009     +17
readtoken1                                          3101    3111     +10
cmdtxt                                               631     641     +10
nodesize                                              27      28      +1
redirect                                             961     916     -45
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/1 up/down: 171/-45)           Total: 126 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-09-02 11:46:11 +02:00
Denys Vlasenko
1cd53c15a2 ash: parser: Invalid redirections are run-time, not syntax errors
Upstream commit

    Date: Wed, 14 Dec 2022 02:06:05 +0100
    parser: Invalid redirections are run-time, not syntax errors

    This fixes a long-standing bug where
      echo 'echo >&a' | sh
    errors out with
      sh: 2: Syntax error: Bad fd number
    despite the error being on line 1

    This patch makes the error
      sh: 1: Bad fd number: a
    as expected

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-11 18:43:02 +02:00
Denys Vlasenko
ea2022efb3 ash: converge waiting code to dash in its form, add comments, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-10 23:39:44 +02:00
Denys Vlasenko
f6fb3c603a ash: move 100 bytes off global .data / .bss, no logic changes
text	   data	    bss	    dec	    hex	filename
1067871	    559	   5184	1073614	 1061ce	busybox_old
1068067	    555	   5088	1073710	 10622e	busybox_unstripped
            ^^^^^^^^^^^
function                                             old     new   delta
pgetc                                                580     623     +43
parse_command                                       1633    1651     +18
ash_main                                            1226    1239     +13
popstring                                            115     126     +11
redirect                                             951     961     +10
popfile                                              105     115     +10
expandstr                                            252     262     +10
evalbltin                                            306     314      +8
pushstring                                           155     162      +7
pushfile                                              31      38      +7
freestrings                                           90      97      +7
setinputstring                                        68      74      +6
readtoken1                                          3095    3101      +6
pungetc                                                9      15      +6
nlprompt                                              39      45      +6
nlnoprompt                                            33      39      +6
unwindfiles                                           20      25      +5
dotcmd                                               309     314      +5
setinputfile                                         190     194      +4
init                                                 429     432      +3
forkchild                                            617     620      +3
evalcommand                                         1616    1617      +1
ash_vmsg                                             141     142      +1
g_parsefile                                            4       -      -4
commandname                                            4       -      -4
basepf                                                84       -     -84
------------------------------------------------------------------------------
(add/remove: 0/3 grow/shrink: 23/0 up/down: 196/-92)          Total: 104 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-10 20:18:10 +02:00
Denys Vlasenko
9b67dde8cd ash: redir: Retry open on EINTR
Upstream commit:

    Date: Thu, 28 May 2020 21:31:45 +1000
    redir: Retry open64 on EINTR

    It is possible for open64 to block on named pipes, and therefore
    it can be interrupted by signals and return EINTR.  We should only
    let it fail with EINTR if real signals are pending (i.e., it should
    not fail on SIGCHLD if SIGCHLD has not been trapped).

    This patch adds a new helper sh_open to retry the open64 call if
    necessary.  It also calls sh_error when appropriate.

    Fixes: 3800d4934391 ("[JOBS] Fix dowait signal race")

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 20:17:31 +02:00
Denys Vlasenko
81274d8b30 ash: eval: Reset handler when entering a subshell
Upstream commit:

    Date: Sun, 3 Mar 2019 21:57:50 +0800
    eval: Reset handler when entering a subshell

    As it is a subshell can execute code that is only meant for the
    parent shell when it executes a longjmp that is caught by something
    like evalcommand.  This patch fixes it by resetting the handler
    when entering a subshell.

function                                             old     new   delta
evalsubshell                                         169     183     +14
evalpipe                                             342     356     +14
argstr                                              1406    1416     +10
ash_main                                            1236    1226     -10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 65/-10)             Total: 28 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 17:52:09 +02:00
Denys Vlasenko
4ce8afe6b2 ahs: jobs: Block signals during tcsetpgrp
Upstream commit:

    Date: Wed, 6 Jan 2021 15:45:12 +1100
    jobs: Block signals during tcsetpgrp

    Harald van Dijk <harald@gigawatt.nl> wrote:
    > On 19/12/2020 22:21, Steffen Nurpmeso wrote:
    >> Steffen Nurpmeso wrote in
    >>   <20201219172838.1B-WB%steffen@sdaoden.eu>:
    >>   |Long story short, after falsely accusing BSD make of not working
    >>
    >> After dinner i shortened it a bit more, and attach it again, ok?
    >> It is terrible, but now less redundant than before.
    >> Sorry for being so terse, that problem crosses my head for about
    >> a week, and i was totally mislead and if you bang your head
    >> against the wall so many hours bugs or misbehaviours in a handful
    >> of other programs is not the expected outcome.
    >
    > I think a minimal test case is simply
    >
    > all:
    >         $(SHELL) -c 'trap "echo TTOU" TTOU; set -m; echo all good'
    >
    > unless I accidentally oversimplified.
    >
    > The SIGTTOU is caused by setjobctl's xtcsetpgrp(fd, pgrp) call to make
    > its newly started process group the foreground process group when job
    > control is enabled, where xtcsetpgrp is a wrapper for tcsetpgrp. (That's
    > in dash, the other variants may have some small differences.) tcsetpgrp
    > has this little bit in its specification:
    >
    >        Attempts to use tcsetpgrp() from a process which is a member of
    >        a background process group on a fildes associated with its con‐
    >        trolling  terminal  shall  cause the process group to be sent a
    >        SIGTTOU signal. If the calling thread is blocking SIGTTOU  sig‐
    >        nals  or  the  process is ignoring SIGTTOU signals, the process
    >        shall be allowed to perform the operation,  and  no  signal  is
    >        sent.
    >
    > Ordinarily, when job control is enabled, SIGTTOU is ignored. However,
    > when a trap action is specified for SIGTTOU, the signal is not ignored,
    > and there is no blocking in place either, so the tcsetpgrp() call is not
    > allowed.
    >
    > The lowest impact change to make here, the one that otherwise preserves
    > the existing shell behaviour, is to block signals before calling
    > tcsetpgrp and unblocking them afterwards. This ensures SIGTTOU does not
    > get raised here, but also ensures that if SIGTTOU is sent to the shell
    > for another reason, there is no window where it gets silently ignored.
    >
    > Another way to fix this is by not trying to make the shell start a new
    > process group, or at least not make it the foreground process group.
    > Most other shells appear to not try to do this.

    This patch implements the blocking of SIGTTOU (and everything else)
    while we call tcsetpgrp.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 17:39:44 +02:00
Denys Vlasenko
df154028dc ash: eval: Add vfork support
Upstream commit:

    Date: Sat, 19 May 2018 02:39:56 +0800
    eval: Add vfork support

    This patch adds basic vfork support for the case of a simple command.

Upstream commit:

    Date: Tue, 12 Jan 2021 17:11:19 +1100
    jobs: Always reset SIGINT/SIGQUIT handlers

    On Fri, Jan 08, 2021 at 08:55:41PM +0000, Harald van Dijk wrote:
    > On 18/05/2018 19:39, Herbert Xu wrote:
    > > This patch adds basic vfork support for the case of a simple command.
    > > ...  @@ -879,17 +892,30 @@ forkchild(struct job *jp, union node *n, int
    > > mode)
    > >   		}
    > >   	}
    > >   	if (!oldlvl && iflag) {
    > > -		setsignal(SIGINT);
    > > -		setsignal(SIGQUIT);
    > > +		if (mode != FORK_BG) {
    > > +			setsignal(SIGINT);
    > > +			setsignal(SIGQUIT);
    > > +		}
    > >   		setsignal(SIGTERM);
    > >   	}
    > > +
    > > +	if (lvforked)
    > > +		return;
    > > +
    > >   	for (jp = curjob; jp; jp = jp->prev_job)
    > >   		freejob(jp);
    > >   }
    >
    > This leaves SIGQUIT ignored in background jobs in interactive shells.
    >
    >   ENV= dash -ic 'dash -c "kill -QUIT \$\$; echo huh" & wait'
    >
    > As of dash 0.5.11, this prints "huh". Before, the subprocess process killed
    > itself before it could print anything. Other shells do not leave SIGQUIT
    > ignored.
    >
    > (In a few other shells, this also prints "huh", but in those other shells,
    > that is because the inner shell chooses to ignore SIGQUIT, not because the
    > outer shell leaves it ignored.)

    Thanks for catching this.  I have no idea how that got in there
    and it makes no sense whatsoever.  This patch removes the if
    conditional.

    Fixes: e94a964e7dd0 ("eval: Add vfork support")

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 17:36:18 +02:00
Denys Vlasenko
9f490785e0 ash: rename got_sigchld, doing_jobctl, and INT_ON/OFF to match dash
Comparing code with dash is more difficult with these differences.
(We didn't know back then that dash will be revived...)

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 17:17:48 +02:00
Denys Vlasenko
53b3854e81 ash: fix fallout of no-more-set commandname
Testsuite reports lots of message mismatches, fix that

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 17:04:16 +02:00
Denys Vlasenko
4eb4141b22 ash: eval: Always set exitstatus in evaltree
Upstream commit:

    Date: Tue, 6 Dec 2022 16:49:14 +0800
    eval: Always set exitstatus in evaltree

    There is no harm in setting exitstatus unconditionally in evaltree.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 12:23:21 +02:00
Denys Vlasenko
6d44762589 ash: options: Do not set commandname in procargs
Upstream commit:

    Date:   Mon Feb 25 12:49:20 2019 +0800
    options: Do not set commandname in procargs

    We set commandname in procargs when we don't have to.  This results
    in a duplicated output of arg0 when an error occurs.

function                                             old     new   delta
ash_main                                            1256    1236     -20

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 02:26:51 +02:00
Denys Vlasenko
98b1a000c9 ash: jobs: drop unused node parameter in makejob()
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 02:02:04 +02:00
Denys Vlasenko
5b3405594a ash: reuse vstype_suffix[] in debug code, shrink it
function                                             old     new   delta
vstype_suffix                                          -      39     +39
static.vstype                                         42       -     -42
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 0/0 up/down: 39/-42)             Total: -3 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-08 12:40:44 +02:00
Denys Vlasenko
422f4ede6f ash: fix cmdputs - was showing some variable forms incorrectly
function                                             old     new   delta
cmdputs                                              402     418     +16
static.vstype                                         48      42      -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 16/-6)              Total: 10 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-07 23:42:45 +02:00
Denys Vlasenko
abab146b82 ash: fix heredoc.tests broken by last commit
function                                             old     new   delta
readtoken1                                          3053    3095     +42
xxreadtoken                                          215     212      -3
expandstr                                            255     252      -3
parseheredoc                                         148     127     -21
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/3 up/down: 42/-27)             Total: 15 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-07 02:26:25 +02:00
Denys Vlasenko
7648dc721e ash,hush: fix corner cases with backslash-newlines in heredocs
function                                             old     new   delta
fetch_heredocs                                       477     485      +8

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-07 01:30:57 +02:00
Denys Vlasenko
d7d8ffed87 shell: typo and whitespace fixes, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 23:29:35 +02:00
Denys Vlasenko
8d3d078917 shell: empty HISTFILE disables history saving, just as unset one did
The rationale here is that unsetting HISTFILE in /etc/profile
does not "stick": if it's unset, the default one is set later
(after /etc/profile is executed) by the shell.
But setting (and exporting, so it is inherited by all
(grand)child shells) an empty one works.

function                                             old     new   delta
save_history                                         296     316     +20

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-07-04 12:51:38 +02:00
Denys Vlasenko
9c46a06885 shell: update HISTFILESIZE code to be actually useful
"HISTFILESIZE=0" in profile wasn't working as intended,
"unset HISTFILE" wasn't preventing creation of history files
Now:
HISTSIZE=n      allows to reduce in-memory history buffer
HISTFILESIZE=n  allows to reduce history file size (0: truncate it)
unset HISTFILE  allows to not save history file at all

function                                             old     new   delta
exitshell                                            138     194     +56
hush_exit                                             97     143     +46
save_history                                         266     296     +30
hush_main                                           1170    1186     +16
.rodata                                           105762  105771      +9
load_history                                         246     254      +8
size_from_HISTFILESIZE                                44      41      -3
read_line_input                                     2746    2712     -34
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 6/2 up/down: 165/-37)           Total: 128 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-07-03 19:10:42 +02:00
Denys Vlasenko
36ac283682 shell: fix race between signal handlers setting bb_got_signal and poll()
function                                             old     new   delta
__ppoll_time64                                         -     211    +211
check_got_signal_and_poll                              -     164    +164
read_key                                             607     601      -6
shell_builtin_read                                  1328    1318     -10
------------------------------------------------------------------------------
(add/remove: 4/0 grow/shrink: 0/2 up/down: 375/-16)           Total: 359 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-07-02 22:42:47 +02:00
Ron Yorston
dcd8df258a shell: improve bash compatibility of read built-in
Make the read built-in more compatible with bash:

- Return an exit code of 142 on timeout.

- When the timeout expires before a newline is detected in the
  input bash captures the partial input.  This behaviour is new
  since bash version 4.4.  BusyBox shells had the pre-4.4 behaviour
  where the input was lost.

Update the tests to suit and fix a couple of compiler errors in
the testsuite.

function                                             old     new   delta
builtin_read                                         154     174     +20
readcmd                                              213     228     +15
shell_builtin_read                                  1364    1370      +6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 41/0)               Total: 41 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-07-01 20:21:37 +02:00
Denys Vlasenko
96b0607302 ash: cache more of uid/gid syscalls
Testcase:
setuidgid 1:1 strace ash -c 'test -x TODO; test -x TODO; echo $?'
should show that second "test -x" does not query ids again.

function                                             old     new   delta
ash_main                                            1236    1256     +20
get_cached_euid                                        -      19     +19
get_cached_egid                                        -      19     +19
test_main                                             56      72     +16
test_exec                                            119     135     +16
is_in_supplementary_groups                            52      57      +5
nexpr                                                718     702     -16
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 4/1 up/down: 95/-16)             Total: 79 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-10-07 07:28:44 +02:00
Denys Vlasenko
d26e958725 ash: make "test -x" use cached groupinfo
function                                             old     new   delta
test_main2                                             -     407    +407
testcmd                                               10      23     +13
test_main                                            418      56    -362
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 420/-362)           Total: 58 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-10-07 07:14:27 +02:00
Denys Vlasenko
4c1d645c86 libbb: simplify parameter passing in is_in_supplementary_groups()
function                                             old     new   delta
is_in_supplementary_groups                            54      52      -2
nexpr                                                721     718      -3
test_exec                                            125     119      -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-11)             Total: -11 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-10-07 06:36:00 +02:00
Denys Vlasenko
860b3d066f ash: command -v CMD must skip (go to next path) when CMD exists, but is not executable
Upstream commit:

    Date: Fri, 5 Apr 2024 17:55:46 +0800
    exec: Check executable bit when searching path

    Andrej Shadura <andrew.shadura@collabora.co.uk> wrote:
    ...
    > https://bugs.debian.org/874264
    > -------- Forwarded Message --------
    > Subject: dash: 'command -v' mistakenly returns a shell script whose
    > executable is not set
    > Date: Mon, 04 Sep 2017 10:45:48 -0400
    > From: Norman Ramsey <nr@cs.tufts.edu>
    > To: Debian Bug Tracking System <submit@bugs.debian.org>
    ...
    > I tracked a build bug in s-nail to a problem with dash.  Symptom:
    > building s-nail tries to run /home/nr/bin/clang, a script whose
    > executable bit is not set.  We tracked the problem to the result of
    > running `command -v clang` with /bin/sh:
    ...
    This is inherited from NetBSD.  There is even a commented-out
    block of code that tried to fix this.

    Anyway, we now have faccessat so we can simply use it.

function                                             old     new   delta
test_exec                                              -     125    +125
find_command                                         911     918      +7
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 132/0)             Total: 132 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-10-07 05:46:31 +02:00
Ron Yorston
24aa93d538 ash: reject unknown long options
Commit 64f70cc755 (Add --login support) added code in options()
to handle the bash-compatible '--login' option.  In doing so it
committed BusyBox ash to silently accepting all other long
options.

Restore compatibility with other ash variants by rejecting unknown
long options.

function                                             old     new   delta
options                                              589     624     +35

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-09-27 21:29:05 +02:00
Ron Yorston
371fe9f71d ash: move hashvar() calls into findvar()
dash has accepted a patch to remove the first argument of findvar().
It's commit e85e972 (var: move hashvar() calls into findvar()).

Apply the same change to BusyBox ash.

function                                             old     new   delta
findvar                                               35      40      +5
mklocal                                              268     261      -7
exportcmd                                            164     157      -7
setvareq                                             319     310      -9
lookupvar                                            150     141      -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/4 up/down: 5/-32)             Total: -27 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-07-14 01:12:54 +02:00
Denys Vlasenko
08fb86726b ash: remove limitation on fd# length
"echo text >&0000000000002" works as you would expect,
"echo text >&9999999999" properly fails instead of creating a file
named "9999999999".

function                                             old     new   delta
expredir                                             219     232     +13
readtoken1                                          3045    3053      +8
parsefname                                           204     201      -3
isdigit_str9                                          45       -     -45
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/1 up/down: 21/-48)            Total: -27 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-07-12 22:28:25 +02:00
Denys Vlasenko
0829fce079 ash: do not abort interactive mode on >&9999 redirect
With very large fd#, the error code path is different
from one for closed but small fd#.

Make it not abort if we are interactive:

$ echo text >&99    # this wasn't buggy
ash: dup2(9,1): Bad file descriptor
$ echo text >&9999  # this was
ash: fcntl(1,F_DUPFD,10000): Invalid argument

function                                             old     new   delta
.rodata                                           105637  105661     +24
dup2_or_raise                                         35      38      +3
redirect                                            1084    1044     -40
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 27/-40)            Total: -13 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-07-12 22:10:50 +02:00
Ron Yorston
0af28b84e5 ash: remove defunct control character to save a few bytes
Commit 549deab5a (ash: move parse-time quote flag detection to
run-time) did away with the need to distinguish between backquotes
inside and outside quotes.  This left a gap among the control
characters used in argument strings.  Removing this gap saves a
few bytes.

function                                             old     new   delta
.rodata                                           167346  167338      -8
cmdputs                                              399     388     -11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-19)             Total: -19 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-07-10 07:35:26 +02:00
Ron Yorston
ba0f94458b ash: fix parsing of alias expansion + bash features
An alias expansion immediately followed by '<' and a newline is
parsed incorrectly:

   ~ $ alias x='echo yo'
   ~ $ x<
   yo
   ~ $
   sh: syntax error: unexpected newline

The echo is executed and an error is printed on the next command
submission.  In dash the echo isn't executed and the error is
reported immediately:

   $ alias x='echo yo'
   $ x<
   dash: 3: Syntax error: newline unexpected
   $

The difference between BusyBox and dash is that BusyBox supports
bash-style process substitution and output redirection.  These
require checking for '<(', '>(' and '&>' in readtoken1().

In the case above, when the end of the alias is found, the '<' and
the following newline are both read to check for '<('.  Since
there's no match both characters are pushed back.

The next input is obtained by reading the expansion of the alias.
Once this string is exhausted the next call to __pgetc() calls
preadbuffer() which pops the string, reverts to the previous input
and recursively calls __pgetc().  This request is satisified from
the pungetc buffer.  But the first __pgetc() doesn't know this:
it sees the character has come from preadbuffer() so it (incorrectly)
updates the pungetc buffer.

Resolve the issue by moving the code to pop the string and fetch
the next character up from preadbuffer() into __pgetc().

function                                             old     new   delta
pgetc                                                 28     589    +561
__pgetc                                              607       -    -607
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/0 up/down: 561/-607)          Total: -46 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-07-10 07:11:23 +02:00
Denys Vlasenko
c5a1be25ba ash: fix handling of single-quoted strings in pattern substitution
function                                             old     new   delta
subevalvar                                          1576    1588     +12

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-02-26 16:27:53 +01:00
zhuyan
ed4a24dfd1 ash: initialize basepf.buf in ash
When I planned to print the command in read_line_input, I found that after
the system started, the command printed for the first time was always
garbled.

After analysis, it is found that in the init() function of ash, the
variable basepf.buf is not initialized after applying for memory, resulting
in garbled initial data. Then assign it to the global variable
g_parsefile->buf in ash.c, and then pass g_parsefile->buf to the parameter
command of the function read_line_input in the function preadfd(), and
finally cause it to be garbled when the command is printed by
read_line_input.

The call stack is as follows:
 #0  read_line_input (st=0xb6fff220, prompt=0xb6ffc910 "\\[\\033[32m\\]\\h \\w\\[\\033[m\\] \\$ ", command=command@entry=0xb6ffc230 "P\325\377\266P\325\377\266", maxsize=maxsize@entry=1024) at libbb/lineedit.c:2461
 #1  0x0043ef8c in preadfd () at shell/ash.c:10812
 #2  preadbuffer () at shell/ash.c:10914
 #3  pgetc () at shell/ash.c:10997
 #4  0x00440c20 in pgetc_eatbnl () at shell/ash.c:11039
 #5  0x00440cbc in xxreadtoken () at shell/ash.c:13157
 #6  0x00440f40 in readtoken () at shell/ash.c:13268
 #7  0x00441234 in list (nlflag=nlflag@entry=1) at shell/ash.c:11782
 #8  0x004420e8 in parsecmd (interact=<optimized out>) at shell/ash.c:13344
 #9  0x00442c34 in cmdloop (top=top@entry=1) at shell/ash.c:13549
 #10 0x00444e4c in ash_main (argc=<optimized out>, argv=0x444e4c <ash_main+1328>) at shell/ash.c:14747
 #11 0x00407954 in run_applet_no_and_exit (applet_no=9, name=<optimized out>, argv=0xbefffd34) at libbb/appletlib.c:1024
 #12 0x00407b68 in run_applet_and_exit (name=0xbefffe56 "ash", argv=0x9) at libbb/appletlib.c:1047
 #13 0x00407f88 in main (argc=<optimized out>, argv=0xbefffd34) at libbb/appletlib.c:1181

Fixes: 82dd14a510 ("ash: use CONFIG_FEATURE_EDITING_MAX_LEN")

Signed-off-by: zhuyan <zhuyan34@huawei.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-08-31 02:20:19 +02:00
Denys Vlasenko
5353df91cb Update applet size estimates
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-07-10 17:25:21 +02:00