[git commit] hush: fix "exec 3>FILE" aborting if 3 is exactly the next free fd

Denys Vlasenko vda.linux at googlemail.com
Fri Jul 12 22:59:02 UTC 2024


commit: https://git.busybox.net/busybox/commit/?id=14e28c18ca1a0fb87b6c73d5cb7487e80bc6713a
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash_test/ash-redir/redir3.right             |  2 +-
 shell/ash_test/ash-redir/redir_exec2.right        |  4 ++++
 shell/ash_test/ash-redir/redir_exec2.tests        | 11 +++++++++++
 shell/ash_test/ash-redir/redir_to_bad_fd255.right |  2 +-
 shell/ash_test/ash-redir/redir_to_bad_fd3.right   |  2 +-
 shell/hush.c                                      | 13 +++++++++----
 shell/hush_test/hush-redir/redir_exec2.right      |  4 ++++
 shell/hush_test/hush-redir/redir_exec2.tests      | 11 +++++++++++
 8 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/shell/ash_test/ash-redir/redir3.right b/shell/ash_test/ash-redir/redir3.right
index fd641a8ea..d9cf5dac5 100644
--- a/shell/ash_test/ash-redir/redir3.right
+++ b/shell/ash_test/ash-redir/redir3.right
@@ -1,3 +1,3 @@
 TEST
-./redir3.tests: line 4: 9: Bad file descriptor
+./redir3.tests: line 4: dup2(9,1): Bad file descriptor
 Output to fd#9: 1
diff --git a/shell/ash_test/ash-redir/redir_exec2.right b/shell/ash_test/ash-redir/redir_exec2.right
new file mode 100644
index 000000000..2bdc093c9
--- /dev/null
+++ b/shell/ash_test/ash-redir/redir_exec2.right
@@ -0,0 +1,4 @@
+fd/5
+fd/4
+fd/3
+One:1
diff --git a/shell/ash_test/ash-redir/redir_exec2.tests b/shell/ash_test/ash-redir/redir_exec2.tests
new file mode 100755
index 000000000..700a51786
--- /dev/null
+++ b/shell/ash_test/ash-redir/redir_exec2.tests
@@ -0,0 +1,11 @@
+cd /proc/$$
+exec 5>/dev/null
+exec 4>/dev/null
+exec 3>/dev/null
+ls -1 fd/5
+ls -1 fd/4
+ls -1 fd/3
+exec 5>&-
+test -e fd/5 && echo BUG
+echo One:$?
+
diff --git a/shell/ash_test/ash-redir/redir_to_bad_fd255.right b/shell/ash_test/ash-redir/redir_to_bad_fd255.right
index 9c5e35b36..ca4df91ac 100644
--- a/shell/ash_test/ash-redir/redir_to_bad_fd255.right
+++ b/shell/ash_test/ash-redir/redir_to_bad_fd255.right
@@ -1,2 +1,2 @@
-./redir_to_bad_fd255.tests: line 2: 255: Bad file descriptor
+./redir_to_bad_fd255.tests: line 2: dup2(255,1): Bad file descriptor
 OK
diff --git a/shell/ash_test/ash-redir/redir_to_bad_fd3.right b/shell/ash_test/ash-redir/redir_to_bad_fd3.right
index 895a4a0a6..5120322a5 100644
--- a/shell/ash_test/ash-redir/redir_to_bad_fd3.right
+++ b/shell/ash_test/ash-redir/redir_to_bad_fd3.right
@@ -1,2 +1,2 @@
-./redir_to_bad_fd3.tests: line 2: 3: Bad file descriptor
+./redir_to_bad_fd3.tests: line 2: dup2(3,1): Bad file descriptor
 OK
diff --git a/shell/hush.c b/shell/hush.c
index afbc3ebec..1d5642260 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -8077,8 +8077,11 @@ static int internally_opened_fd(int fd, struct squirrel *sq)
 	return 0;
 }
 
-/* squirrel != NULL means we squirrel away copies of stdin, stdout,
- * and stderr if they are redirected. */
+/* sqp != NULL means we squirrel away copies of stdin, stdout,
+ * and stderr if they are redirected.
+ * If redirection fails, return 1. This will make caller
+ * skip command execution and restore already created redirect fds.
+ */
 static int setup_redirects(struct command *prog, struct squirrel **sqp)
 {
 	struct redir_struct *redir;
@@ -8109,7 +8112,7 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
 				 * "cmd > <file" (2nd redirect starts too early)
 				 */
 				syntax_error("invalid redirect");
-				continue;
+				return 1;
 			}
 			mode = redir_table[redir->rd_type].mode;
 			p = expand_string_to_string(redir->rd_filename,
@@ -8124,7 +8127,9 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
 				 */
 				return 1;
 			}
-			if (newfd == redir->rd_fd && sqp) {
+			if (newfd == redir->rd_fd && sqp
+			 && sqp != ERR_PTR /* not a redirect in "exec" */
+			) {
 				/* open() gave us precisely the fd we wanted.
 				 * This means that this fd was not busy
 				 * (not opened to anywhere).
diff --git a/shell/hush_test/hush-redir/redir_exec2.right b/shell/hush_test/hush-redir/redir_exec2.right
new file mode 100644
index 000000000..2bdc093c9
--- /dev/null
+++ b/shell/hush_test/hush-redir/redir_exec2.right
@@ -0,0 +1,4 @@
+fd/5
+fd/4
+fd/3
+One:1
diff --git a/shell/hush_test/hush-redir/redir_exec2.tests b/shell/hush_test/hush-redir/redir_exec2.tests
new file mode 100755
index 000000000..700a51786
--- /dev/null
+++ b/shell/hush_test/hush-redir/redir_exec2.tests
@@ -0,0 +1,11 @@
+cd /proc/$$
+exec 5>/dev/null
+exec 4>/dev/null
+exec 3>/dev/null
+ls -1 fd/5
+ls -1 fd/4
+ls -1 fd/3
+exec 5>&-
+test -e fd/5 && echo BUG
+echo One:$?
+


More information about the busybox-cvs mailing list