aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2026-01-29 08:02:09 +0000
committerRon Yorston <rmy@pobox.com>2026-01-29 08:02:09 +0000
commit4c41b562c07c20c6df03d0cda3e28bda3295ffba (patch)
tree013247ade809929f9c581c05d9aca591b0778f4c /shell
parent04eadd2f424f491b5c77f4a247dc0b6da3b9aef2 (diff)
downloadbusybox-w32-4c41b562c07c20c6df03d0cda3e28bda3295ffba.tar.gz
busybox-w32-4c41b562c07c20c6df03d0cda3e28bda3295ffba.tar.bz2
busybox-w32-4c41b562c07c20c6df03d0cda3e28bda3295ffba.zip
ash: don't skip exec() if std streams are invalidHEADmaster
This didn't produce the expected output when run from ash: ash -c "echo abc | sed s/a/x/" <&- In general, if the last command in the pipe read from stdin the command didn't work; if it read from file descriptor 0 (e.g. cat) it did. Closing a file descriptor caused the corresponding stream to become invalid. For performance reasons the shell in busybox-w32 runs applets without an exec(), but that results in their seeing the invalid stream from their parent. Avoid the problem by calling exec() in such cases. This causes the child process to get a new stdin stream initialised from the file descriptor. The test also applies to stdout and stderr. There's no discernable affect on performance when running the test suite. Adds 64-96 bytes. (GitHub issue #558)
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 330de607f..90e9168be 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9318,7 +9318,9 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9318 /* Treat all applets as NOEXEC, including the shell itself 9318 /* Treat all applets as NOEXEC, including the shell itself
9319 * if we were called from forkshell_shellexec(). */ 9319 * if we were called from forkshell_shellexec(). */
9320 run_noexec: 9320 run_noexec:
9321 if (applet_main[applet_no] != ash_main || noexec) { 9321 if ((applet_main[applet_no] != ash_main || noexec) &&
9322 fileno(stdin) != -2 && fileno(stdout) != -2 &&
9323 fileno(stderr) != -2) {
9322 /* mingw-w64's getopt() uses __argv[0] as the program name */ 9324 /* mingw-w64's getopt() uses __argv[0] as the program name */
9323 __argv[0] = (char *)cmd; 9325 __argv[0] = (char *)cmd;
9324 /* 'which' wants to know if it was invoked from a standalone 9326 /* 'which' wants to know if it was invoked from a standalone