diff options
| author | Ron Yorston <rmy@pobox.com> | 2026-01-29 08:02:09 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2026-01-29 08:02:09 +0000 |
| commit | 4c41b562c07c20c6df03d0cda3e28bda3295ffba (patch) | |
| tree | 013247ade809929f9c581c05d9aca591b0778f4c | |
| parent | 04eadd2f424f491b5c77f4a247dc0b6da3b9aef2 (diff) | |
| download | busybox-w32-4c41b562c07c20c6df03d0cda3e28bda3295ffba.tar.gz busybox-w32-4c41b562c07c20c6df03d0cda3e28bda3295ffba.tar.bz2 busybox-w32-4c41b562c07c20c6df03d0cda3e28bda3295ffba.zip | |
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)
| -rw-r--r-- | shell/ash.c | 4 |
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 |
