aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* which,ash: code shrink detection of standalone shellRon Yorston2024-08-171-13/+9
| | | | | | | | | | | | | | | | | | | | | | Commit 6d87be4d7 (which,ash: changes to which/command/type) let 'which' detect when it's run from a standalone shell by having the shell pass the undocumented '-s' option. A better solution is to alter argv[0] when 'which' is run from a standalone shell. This is possible because the code path through run_noexec_applet_and_exit() and which_main() doesn't actually use argv[0]. - No special treatment is required in ash when 'which' has no arguments or the '--help' option. - tryexec() no longer needs an extra element before the start of argv. The commit 027fb22e2 can be reverted and the allocation of argv in evalcommand() simplified. - 'which' no longer needs to handle the '-s' option. Saves 96-104 bytes.
* ash: allow additional element in argv arrayRon Yorston2024-08-161-2/+5
| | | | | | | | | | | | | | | | tryexec() in ash relies on all callers of shellexec() having an additional unused element before the start of its argv array. In busybox-w32 this was not the case when shellexec() was called from forkshell_shellexec(), as only the actual contents of the argv array were copied into the forkshell data block. In practice argv[-1] is only currently used when the 'which' applet is about to be run, so whatever got overwritten (probably cmdtable[30]) was unlikely to matter. Still, let's be correct and allocate the additional element. Adds 16 bytes.
* ash: rewrite waitpid_child() to improve performanceRon Yorston2024-07-301-32/+19
| | | | | | | | | | | | | | | | | | | | After the previous commit there was still a slight disparity between shell performance with and without background jobs. Reduce this disparity by the following changes: - Remove the pidlist array. The PID of the exiting process can be obtained from its handle. - Save the proclist array between calls. It will always grow to support the required number of PIDs. - Combine the loops to compute the required size of proclist and to fill it. This saves a few bytes with no measurable impact on performance. Saves 8 bytes in a 32-bit build, adds 32 in 64-bit. (GitHub issue #434)
* ash: fix slow running when background job is presentRon Yorston2024-07-281-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | It was noted that a simple 'while' loop would take considerably longer to run in a shell which had spawned a background job compared to one that hadn't. The problem originates with commit 4d8a277d59 (Implement nonblocking wait) which introduced a nonblocking wait in ash. This was found to cause the shell to use 100% of CPU when running 'sleep 60'. This was 'fixed' by commit 88b8cb61e (ash: Add a very small timeout to nonblocking wait). Subsequently commit 96c9c0044 (ash: allow waitpid_child to block) fixed a problem with the logic of the original commit, but it left the small timeout in place. It is this timeout which slows down the shell when a background job is present. The solution is to restore the 0 timeout for the nonblocking wait. Saves 0-16 bytes. (GitHub issue #434)
* ash: ignore hidden/iconified stateRon Yorston2024-07-181-10/+3
| | | | | | | | | | | | | | | Some third-party terminal programs have a hidden console host to interact with console applications. When the busybox-w32 shell was used with such a terminal the hidden console host could be revealed because the shell expected it to be iconified. Since it doesn't much matter in this case whether the console host is hidden or iconified treat these states as equivalent. The user's preference set by the 'noiconify' option will still be respected when a console window is concealed. (GitHub issue #430)
* Merge branch 'busybox' into mergeRon Yorston2024-07-141-12/+10
|\
| * ash: move hashvar() calls into findvar()Ron Yorston2024-07-141-9/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* | Merge branch 'busybox' into mergeRon Yorston2024-07-131-11/+29
|\|
| * ash: remove limitation on fd# lengthDenys Vlasenko2024-07-121-7/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | "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>
| * ash: do not abort interactive mode on >&9999 redirectDenys Vlasenko2024-07-121-4/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* | Merge branch 'busybox' into mergeRon Yorston2024-07-101-21/+12
|\|
| * ash: remove defunct control character to save a few bytesRon Yorston2024-07-101-12/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
| * ash: fix parsing of alias expansion + bash featuresRon Yorston2024-07-101-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* | ash: restore value of imported variable on unexportRon Yorston2024-07-081-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Shell variables imported from the environment are marked with a special flag and backslashes in their values are (by default) replaced with forward slashes. Sometimes this may not be what we want. Modify the 'export' shell built-in so unexporting a variable of this type restores its original value from the environment and removes its special flag. It can then be re-exported. Adds 32 bytes. (GitHub issue #428)
* | ash: read profile script relative to binaryRon Yorston2024-07-081-0/+4
| | | | | | | | | | | | | | As well as trying to read '/etc/profile' also look for the script 'etc/profile' relative to the location of the running binary. Adds 64-96 bytes.
* | win32: code shrink system drive handlingRon Yorston2024-07-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A previous commit (e3bfe3695) revised the use of getsysdir() to obtain the system directory, and hence the system drive. See the commit message for the history to that point. Further improvements are possible: - Remove getsysdir() and push the calls to GetSystemDirectory() down into get_system_drive() and get_proc_addr(). - Check the return value of GetSystemDirectory(). It's unlikely to fail, but better safe than sorry. - Instead of making all callers of get_system_drive() check for a NULL return value always return a non-NULL pointer. If the drive can't be found an empty string is returned instead (which is what the callers were using anyway). - The function need_system_drive() was only used in one place (in httpd). Move the code there and remove the function. - Use concat_path_file() where possible. Saves 76-144 bytes.
* | ash: special hack for libtoolRon Yorston2024-07-071-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | Libtool assumes the host environment is MSYS2 and will be confused by Windows-style command switches. The "/c" in "cmd /c" looks like a path, which MSYS2 incorrectly decodes to "c:/". Anticipating this, libtool encodes these calls as "cmd //c" which does not work outside MSYS2. A busybox-w32 patch makes it behave like MSYS2 in just this one case. Adds 88-96 bytes. (GitHub issue #297 and https://github.com/skeeto/w64devkit/issues/50)
* | win32: properly restore BB_ env varsRon Yorston2024-07-021-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Some BB_ shell variables get special treatment: they're updated in the environment immediately on any change. One case was missed: if such a variable was unset or not exported and was overridden by a local variable it wasn't unset in the environment when the local variable went out of scope. Add the code required to do this. Adds 48-64 bytes. (GitHub issue #423)
* | Merge branch 'busybox' into mergeRon Yorston2024-06-231-0/+5
|\|
| * ash: fix handling of single-quoted strings in pattern substitutionDenys Vlasenko2024-02-261-0/+5
| | | | | | | | | | | | | | function old new delta subevalvar 1576 1588 +12 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* | win32: add env var to control error dialogsRon Yorston2024-06-221-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the environment variable BB_CRITICAL_ERROR_DIALOGS is set to 1 critical error dialogs are enabled. If unset or set to any other value they aren't. In either case the error messages introduced by commit 790e37727 (win32: revert 'don't set error mode') are issued. The shell exports BB_CRITICAL_ERROR_DIALOGS to the environment immediately on any change so the setting takes effect at once. Adds 104-160 bytes. (GitHub issue #423)
* | win32: allow for trailing separator in PATHRon Yorston2024-06-141-38/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In recent versions of Windows the PATH environment variable has a trailing semicolon. This is insignificant to Windows because it's ignored. busybox-w32 conforms to the POSIX interpretation of PATH which treats an empty path element as denoting the current directory. As result, on these versions of Windows executables may by default be run from the current directory, contrary to usual Unix practice. Attempt to detect and remove the trailing semicolon on applet start up. If the user insists, they can add a trailing semicolon to the shell variable PATH and it will be respected in the conventional manner. Adds 88-112 bytes. (GitHub issue #422)
* | ash: fix commentRon Yorston2024-05-221-1/+1
| |
* | ash: prevent mintty from setting HOMERon Yorston2024-05-211-1/+13
| | | | | | | | | | | | | | | | | | | | The Cygwin terminal program mintty sets the HOME environment variable. Attempt to detect this and unset HOME so the usual busybox-w32 initialisation of HOME is used instead. Adds 80 bytes. (GitHub issue #420)
* | ash: -X option shouldn't alter environment variablesRon Yorston2024-05-101-3/+3
| | | | | | | | | | | | | | | | | | | | When a shell was started with the -X option, environment variables had forward slashes changed to backslashes. This is unnecessary and counterproductive. Adjust how the state of winxp is handled to avoid this. (GitHub issue #415)
* | ash: fix typoRon Yorston2024-04-301-1/+1
| |
* | ash: fix alias expansion followed by '&'Ron Yorston2024-04-301-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An alias expansion immediately followed by '&' is parsed incorrectly: ~ $ alias x='sleep 2' ~ $ x& ~ $ sh: syntax error: unexpected "&" The sleep happens in the foreground and the '&' is left in the input buffer. The same problem occurs in upstream BusyBox but not dash. The difference between BusyBox and dash is that BusyBox supports bash-style output redirection (BASH_REDIR_OUTPUT in the code). This requires checking for '&>' in readtoken1(). 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 alias is then expanded and __pgetc() is called to fetch the next character. Since there are none left in the alias string __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(). Saves 32-48 bytes. (GitHub issue #413)
* | ash: add 'noiconify' optionRon Yorston2024-04-291-11/+23
| | | | | | | | | | | | | | | | | | | | The 'noiconify' option controls how the console window is concealed when the 'noconsole' option is used. The default is to iconify the console. When 'noiconify' is 'on' the console is hidden. Adds 8-16 bytes. (GitHub issue #325)
* | ash: detect console state on every call to options()Ron Yorston2024-04-291-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 67ed7484be (ash: detect console state on shell start up) synchronised the noconsole option with the actual state of the window on shell start up. This is insufficient. The user can change the state of the window independently of the noconsole option, leading to confusion and unwanted iconification of the window when unrelated 'set' commands are issued. Detect the current console state on every call to options(). Saves 16-32 bytes. (GitHub issue #325)
* | win32: adjust handling of executable extensionsRon Yorston2024-04-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Mixing Windows and Unix-style filename extensions was causing problems. Tweak how extensions are handled to try and improve matters: - Consistently check whether the unaltered filename is an executable before trying adding extensions. - Check .exe and .com before .sh. Saves up to 16 bytes. (GitHub issue #405)
* | ash: move setting of current directoryRon Yorston2024-04-091-5/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The undocumented '-d' shell option is used to set the current directory in shells started by the 'su' applet of busybox-w32. In this case, the shell isn't a login shell. If a login shell sets the current working directory in /etc/profile it's possible the user may wish to override this with '-d'. This didn't work, though, because the directory is changed before /etc/profile is processed. Move the changing of the directory to that specified by '-d' so it happens after the processing of /etc/profile and ~/.profile. This won't affect the intended use of '-d'. (GitHub issue #403)
* | ash: add title built-inRon Yorston2024-04-091-0/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Implement a 'title' built-in for ash. It's very simple-minded, performs almost no error checking and is completely non-portable. - With no arguments it prints the current console title. - If arguments are provided the *first only* is set as the console title. Costs 88-116 bytes. (GitHub issue #401)
* | ash: strip path from NOFORK applet namesRon Yorston2024-03-261-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 26ba73098 (win32: search PATH for missing Unix-style executables) extended the cases in which PATH would be searched for executables specified with a Unix-style path. A side effect of this change was to pass the Unix-style path as argv[0] to NOFORK applets. The 'uname' applet examines argv[0] to determine how to behave. When invoked as '/bin/uname' it returned unexpected results. Other applets may be similarly affected. When a NOFORK applet is invoked in evalcommand(), strip any path. Costs 16 bytes. (GitHub issue #392)
* | ash: allow nofork applets in Windows on ARM + UCRTRon Yorston2024-02-081-1/+2
| | | | | | | | | | | | | | | | | | | | Commit ea8742bc16 (ash: workaround environment issue in Windows on ARM) prevented nofork applets from being run without a fork in standalone shell mode in Windows on ARM. This was due to a deficiency in the handling of the 'environ' global. However, the problem is specific to MSVCRT. If the target is UCRT nofork applets can be made to work without a fork.
* | win32: rearrange applet override handlingRon Yorston2024-02-021-5/+5
| | | | | | | | | | | | | | | | | | | | - Rename some functions to be more meaningful. - Adjust conditional compilation to clarify which code is required for 'standalone shell' and 'exec prefers applets' settings. This shouldn't result in any change to the behaviour or size of default builds.
* | Fix POSIX build in standalone shell modeRon Yorston2024-01-231-2/+2
| | | | | | | | | | | | | | The conditional compilation to control standalone shell mode was incorrect when building for POSIX. This hadn't been noticed before as it had only been tested in the default configuration where standalone shell mode is disabled.
* | ash: workaround environment issue in Windows on ARMRon Yorston2024-01-181-1/+2
| | | | | | | | | | | | | | The environment is handled differently in ARM64 Windows. Assignments to 'environ' result in a compiler error. Omit the offending code for now. NOFORK applets will cause a fork.
* | ash: further reduce forkshell relocation blockRon Yorston2024-01-161-17/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Following on from commit c84b81ce4 (ash: reduce size of forkshell relocation block): - Store the flags to indicate if annotations should be freed in a separate array. This only affects builds with forkshell debug enabled. - Use a bitmap to indicate which pointers need relocation (instead of an array of bytes). This reduces the size of the forkshell data block by a few hundred bytes. Adds 32-64 bytes.
* | ash: reduce size of forkshell relocation blockRon Yorston2024-01-151-12/+12
| | | | | | | | | | | | | | | | | | | | | | | | The forkshell relocation block had one byte for each byte of the forkshell structure and funcblock. It's only necessary to allow one byte for each pointer. (One or two bits would be enough, but would make the code more complex.) The impact of this change depends on the data and whether the CPU is 32- or 64-bit. It typically saves a few Kbytes. Costs 16-52 bytes.
* | ash: code shrink forkshell debugRon Yorston2024-01-151-6/+0
| | | | | | | | | | | | | | | | Remove a check that there are no relocations for addresses in the funcstring block. At one point during development the relocation block had entries for that area, but not any more. This only affects non-default builds with forkshell debug enabled.
* | ash: add more checks to forkshell debugRon Yorston2024-01-141-15/+36
| | | | | | | | | | | | Rearrange the handling of pointer relocation during forkshell and add a couple of additional sanity checks. There's no functional change to non-debug builds.
* | ash: special case in creation of pipelineRon Yorston2024-01-141-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | When a pipeline is created the parent allocates an array of procstat structures sufficient for the number of members of the pipeline. The child processes, however, only see the number of processes created so far. Thus, the first child sees that a procstat array has been created but contains no processes. This resulted in an invalid pointer to the procstat array in the first child. This probably doesn't matter: if the number of processes is zero there should be no need to access the array. Set the pointer to NULL so if it is accessed we'll know about it.
* | win32: make the clang build less crashyRon Yorston2024-01-031-6/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | busybox-w32 binaries built using clang crashed so frequently that they were pretty much unusable. The main issue seems to be with assignments to the structures containing global variables which are used in most applets. Upstream commit 5156b2455 (Make const ptr assign as function call in clang) addresses this, but is insufficient for the build on Windows. Extend the idea to the ASSIGN_CONST_PTR() macro too. Costs 32-80 bytes in the gcc build.
* | ash: avoid crash when job table is emptyRon Yorston2023-12-251-6/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 7b692ddf0 (ash: improved support for jobs built-in) didn't correctly initialise the pointer to the job table if it was empty. This resulted in the following crashing: sh -c "cat <(echo HelloWorld | rev)" Fix forkshell_copy() so the job table pointer is NULL if there are no jobs. Adds 16 bytes. (GitHub issue #379)
* | win32: code shrink applet overridesRon Yorston2023-12-101-45/+4
| | | | | | | | | | | | | | | | Pass the PATH to be used to look up executables down from the shell to the applet override code. This replaces the use of a static variable and a function to fetch its value. Saves 16-32 bytes.
* | ash: add options to control globbing of hidden filesRon Yorston2023-09-201-8/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add shell options: - 'nohiddenglob' excludes files with the hidden attribute from globbing - 'nohidsysglob' excludes files with the hidden and system attributes from globbing If both options are enabled 'nohiddenglob' takes precedence. These options also affect tab completion. Files that are hidden because they start with a period aren't affected (unless they also have the hidden attribute). Costs 160-208 bytes. (GitHub issue #367)
* | win32: convert exit codesRon Yorston2023-09-141-13/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add two utility functions to convert Windows process exit codes. - exit_code_to_wait_status() converts to a POSIX wait status. This is used in ash and the implementations of system(3) and mingw_wait3(). - exit_code_to_posix() converts to a POSIX exit code. (Not that POSIX has much to say about them.) As a result it's possible for more applets to report when child processes are killed as if by a signal. 'time', 'drop' and 'su -W', for example. Adds 64-80 bytes.
* | ash: fix signal handlingRon Yorston2023-09-131-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 89aa9d783 (win32: changes to signal handling) caused a regression: 'httpd -f' could no longer be interrupted by Ctrl-C. The specific issue is the use of exit(2) to replace raise(3) in raise_interrupt(). This change was made so the shell would return the expected exit code of 130 rather than the default code of 3 which Windows uses when a signal with SIG_DFL disposition is caught. The problem can be avoided by calling _exit(2) instead. A call to fflush_all() has also been added, as _exit(2) doesn't do that. (GitHub issue #365)
* | ash: initialize basepf.buf in ash (2)Ron Yorston2023-08-311-1/+1
| | | | | | | | | | | | Upstream commit ed4a24dfd (ash: initialize basepf.buf in ash) zeroes out the memory allocated for basepf.buf. busybox-w32 has a copy of this code early in ash_main(). Do the same there.
* | Merge branch 'busybox' into mergeRon Yorston2023-08-311-1/+1
|\|