Commit graph

1119 commits

Author SHA1 Message Date
Denys Vlasenko
9b2a50efe2 *: use xasprintf_inplace() in more places
function                                             old     new   delta
.rodata                                           107009  107018      +9
parse_stream                                        3075    3069      -6
buffer_print                                         612     603      -9
expand_args                                          159     144     -15
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/3 up/down: 9/-30)             Total: -21 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-02-06 11:19:11 +01:00
Denys Vlasenko
3681b5f618 hush: changes to comments and whitespace, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-09-03 13:36:35 +02:00
Denys Vlasenko
b4cedd4c9a hush: fix several syntax corner cases with function definitions
function                                             old     new   delta
parse_stream                                        3063    3075     +12
done_word                                            777     784      +7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 19/0)               Total: 19 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-18 14:52:46 +02:00
Denys Vlasenko
5d66c8a602 hush: shrink "function" code
function                                             old     new   delta
done_word                                            766     777     +11
static.reserved_match                                 16      12      -4
reserved_list                                        240     168     -72
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 11/-76)            Total: -65 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-18 13:55:09 +02:00
Denys Vlasenko
5c2c2916fc hush: do not SEGV on if { echo foo; } then { echo bar; } fi
For some reason, it was only happening in interactive use

function                                             old     new   delta
initialize_context                                    39      54     +15
parse_stream                                        3077    3063     -14
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 15/-14)              Total: 1 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-18 13:37:09 +02:00
Denys Vlasenko
2bdec03def hush: disentangle keyword detection, no logic changes
function                                             old     new   delta
done_word                                            790     766     -24

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-18 13:14:26 +02:00
Denys Vlasenko
2ccb891819 hush: make "function" keyword support optional
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 17:59:30 +02:00
Denys Vlasenko
84d4ac3754 hush: with --login, errors /etc/profile in must not exit shell
function                                             old     new   delta
die_if_script                                         28      34      +6
hush_main                                           1146    1150      +4
run_list                                            1031    1028      -3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 10/-3)               Total: 7 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 17:39:04 +02:00
Denys Vlasenko
96466951bf hush: recognize "function FUNC { cmd; }" syntax
function                                             old     new   delta
reserved_list                                          -     240    +240
parse_stream                                        2923    3077    +154
done_word                                            771     790     +19
.rodata                                           105975  105992     +17
static.reserved_match                                 12      16      +4
static.reserved_list                                 168       -    -168
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 4/0 up/down: 434/-168)          Total: 266 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 14:33:00 +02:00
Denys Vlasenko
a30882dec5 hush: remove always-true conditional
function                                             old     new   delta
parse_stream                                        2940    2923     -17

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 13:47:34 +02:00
Denys Vlasenko
36f1b16b05 hush: fix infinite loop expanding alias a="nice&&a"
function                                             old     new   delta
parse_stream                                        2857    2940     +83
i_peek                                                55      69     +14
i_free_alias_buffer                                   33      37      +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 101/0)             Total: 101 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 05:03:41 +02:00
Denys Vlasenko
1a947654b5 hush: comment fixes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 04:17:45 +02:00
Denys Vlasenko
94cb769b65 hush: make "alias" print aliases in properly escaped form
function                                             old     new   delta
print_pfx_escaped_nl                                   -      83     +83
builtin_alias                                        216     218      +2
.rodata                                           105985  105975     -10
parse_stream                                        2873    2857     -16
builtin_set                                          301     259     -42
builtin_readonly                                     107      59     -48
builtin_export                                       145      93     -52
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/5 up/down: 85/-168)           Total: -83 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 04:07:42 +02:00
Denys Vlasenko
7423bbbe98 hush: fix nested alias expansion
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 03:24:13 +02:00
Denys Vlasenko
5ba6ad7733 hush: optional alias support
function                                             old     new   delta
parse_stream                                        2540    2873    +333
i_getch                                               85     410    +325
builtin_alias                                          -     216    +216
builtin_unalias                                        -     185    +185
.rodata                                           105806  105985    +179
word_matches_alias                                     -      82     +82
find_alias_slot                                        -      77     +77
end_of_alias_name                                      -      69     +69
builtin_type                                         128     179     +51
i_free_alias_buffer                                    -      33     +33
enable_all_aliases                                     -      29     +29
bltins1                                              396     420     +24
o_reset_to_empty_unquoted                              -      21     +21
run_pipe                                            1554    1566     +12
i_peek                                                57      55      -2
parse_redirect                                       351     346      -5
redirect_opt_num                                      63      53     -10
encode_then_append_var_plusminus                     552     532     -20
done_word                                            796     771     -25
i_getch_interactive                                  308       -    -308
------------------------------------------------------------------------------
(add/remove: 8/1 grow/shrink: 6/5 up/down: 1636/-370)        Total: 1266 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-17 02:51:35 +02:00
Denys Vlasenko
5806d2a3db hush: optimization in set_local_var()
function                                             old     new   delta
set_local_var                                        416     409      -7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-16 01:53:46 +02:00
Denys Vlasenko
3e766dce5f hush: implement <<<here_string syntax
function                                             old     new   delta
setup_heredoc                                        299     351     +52
parse_stream                                        2514    2540     +26
parse_redirect                                       335     351     +16
redir_table                                           40      48      +8
static.setup_redirects                               394     400      +6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/0 up/down: 108/0)             Total: 108 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-15 00:08:11 +02:00
Denys Vlasenko
0d1f6a54f7 hush: allow faster parsing for "./:@" characters
function                                             old     new   delta
parse_stream                                        2513    2514      +1

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 20:08:19 +02:00
Denys Vlasenko
a8f20420a5 hush: shrink syntax error handling
Was trying to add code to reject more invalid "case" syntaxes, but it's not that easy

function                                             old     new   delta
done_word                                            795     796      +1
parse_stream                                        2529    2513     -16
.rodata                                           105825  105806     -19
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 1/-35)             Total: -34 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 19:47:20 +02:00
Denys Vlasenko
6cc3380105 hush: undo incorrect change which allows a'b'=c to be assignment
While at it, remove now-unused WORD_IS_KEYWORD

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 16:19:58 +02:00
Denys Vlasenko
cad5a79bd4 hush: explain "empty quoted str marker" trick
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 12:03:24 +02:00
Denys Vlasenko
4343ca9aa8 hush: improve code readability, no logic changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 11:08:08 +02:00
Denys Vlasenko
d029e80187 hush: remove the is_blank dance
function                                             old     new   delta
parse_stream                                        2566    2524     -42

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 04:04:57 +02:00
Denys Vlasenko
2bb8b9b2a4 hush: remove two strchr's from the hottest parsing loop
function                                             old     new   delta
parse_stream                                        2572    2566      -6

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 02:30:32 +02:00
Denys Vlasenko
438b92efdd hush: optimize decoding of $'str' - avoid extra function call if we can
function                                             old     new   delta
parse_stream                                        2565    2572      +7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-13 23:20:10 +02:00
Denys Vlasenko
f29ab91763 hush: shrink i_getch, rename two functions
Final link with: <none>
function                                             old     new   delta
i_getch_interactive                                    -     308    +308
i_getch                                              102      85     -17
fgetc_interactive                                    309       -    -309
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 0/1 up/down: 308/-326)          Total: -18 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-13 17:30:48 +02:00
Denys Vlasenko
187f24b490 hush: ~5% faster parsing of typical shell scripts
0-9,A-Z,a-z are never special and just go into the current word.

function                                             old     new   delta
parse_stream                                        2476    2565     +89

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-13 10:01:16 +02:00
Denys Vlasenko
a5cf673c9c hush: create a macro IS_NULL_WORD to test for null shell word
No logic changes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-13 02:30:09 +02:00
Denys Vlasenko
1847fee2d4 hush: fix a corner case in "case" stmt, ctx_dsemicolon is in fact unused
function                                             old     new   delta
parse_stream                                        2446    2476     +30
done_word                                            797     800      +3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 33/0)               Total: 33 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-13 00:51:44 +02:00
Denys Vlasenko
f161bc628f hush: allow nested negation "! ! ! CMD" - bash 5.2.15 allows it
Also, deindent "ch == EOF" code branch in parse_stream()

function                                             old     new   delta
done_word                                            799     797      -2
parse_stream                                        2453    2446      -7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-9)               Total: -9 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-12 20:29:26 +02:00
Denys Vlasenko
2b0b74e8b4 hush: drop ctx_inverted, use pipe->pi_inverted
function                                             old     new   delta
done_word                                            776     799     +23
parse_stream                                        2456    2453      -3
done_pipe                                            252     242     -10
.rodata                                           105837  105825     -12
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/3 up/down: 23/-25)             Total: -2 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-12 20:29:26 +02:00
Denys Vlasenko
5ecbed0e26 hush: do not segfault on "for </dev/null v in..."
This is not accepted by bash, we may also disallow this,
but for now, at least do not crash

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-12 17:56:58 +02:00
Denys Vlasenko
ab1de7df99 hush: test for, and disallow several invalid syntaxes
function                                             old     new   delta
parse_stream                                        2292    2456    +164
done_pipe                                            231     252     +21
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 185/0)             Total: 185 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-11 23:18:01 +02:00
Denys Vlasenko
0da6c813e1 hush: fix var_backslash1.tests
function                                             old     new   delta
o_addqblock                                            -     131    +131
append_str_maybe_ifs_split                            53     100     +47
expand_one_var                                      1872    1897     +25
encode_then_expand_vararg                            380     399     +19
sig_unblock                                           41      43      +2
sig_block                                             41      40      -1
sigprocmask_allsigs                                   33      31      -2
expand_vars_to_list                                 1080    1077      -3
wait_for_child_or_signal                             202     193      -9
o_addQstr                                            175      42    -133
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/5 up/down: 224/-148)           Total: 76 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-11 17:36:02 +02:00
Denys Vlasenko
e660eab458 *: code shrink using sigprocmask2() where appropriate
function                                             old     new   delta
sig_unblock                                           41      43      +2
sig_block                                             41      40      -1
sigprocmask_allsigs                                   33      31      -2
wait_for_child_or_signal                             202     193      -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/3 up/down: 2/-12)             Total: -10 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-11 01:17:02 +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
34948f1858 hush: smarter optimization for not-globbing [ and [[
function                                             old     new   delta
o_save_ptr                                           176     167      -9

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-07 02:46:04 +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
558ef4962d hush: optimization: do not glob words "[" and "[["
function                                             old     new   delta
glob_needed                                           71      86     +15

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-07 00:20:56 +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
02b518db1c hush: fix memory leak caused by compiler optimizing out a store
function                                             old     new   delta
generate_stream_from_string                          222     232     +10
setup_heredoc                                        329     330      +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 11/0)               Total: 11 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 20:42:52 +02:00
Denys Vlasenko
58a54fbd5a hush: disentangle interactiveness/job_control setup code
...and discover that we can do away with 1-3 initialization syscalls.

function                                             old     new   delta
hush_main                                           1152    1146      -6

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 17:37:32 +02:00
Denys Vlasenko
778fce3e70 hush: fix build failure if !CONFIG_HUSH_JOB
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 16:22:21 +02:00
Denys Vlasenko
dba57344b5 hush: make NORETURN declarations lees verbose, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 16:14:19 +02:00
Denys Vlasenko
4539262b6a hush: do not save history on xfunc error, it's unsafe
Also, make second calls to install_special_sighandlers() less haphazard.
It's not a fix for anything, but looking more organized now.

function                                             old     new   delta
fflush_restore_ttypgrp_and__exit                       -      20     +20
restore_ttypgrp_and__exit                             21       -     -21
hush_main                                           1181    1152     -29
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 0/1 up/down: 20/-50)            Total: -30 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 16:12:00 +02:00
Denys Vlasenko
cdbb6957f1 hush: don't save history in subshells; on NOMMU, don't be interactive on reexec
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 01:26:25 +02:00
Denys Vlasenko
e591316e02 hush: rename hush_exit to save_history_run_exit_trap_and_exit, sigexit to restore_ttypgrp_and_killsig_or__exit
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 00:44:32 +02:00
Denys Vlasenko
e9c21c5c3a hush: fix SEGV on "echo << >" and such
function                                             old     new   delta
.rodata                                           105787  105823     +36
fetch_heredocs                                       461     477     +16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 52/0)               Total: 52 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-07-08 10:36:12 +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