← Commit list

14e28c18c

Denys Vlasenko
Denys Vlasenko
2024-07-13
SUCCESS Duration: 155s

Subject

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

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

shell/ash_test/ash-redir/redir3.right+1 -1
@@ -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
shell/ash_test/ash-redir/redir_exec2.right+4 -0
@@ -0,0 +1,4 @@
+fd/5
+fd/4
+fd/3
+One:1
shell/ash_test/ash-redir/redir_exec2.tests+11 -0
@@ -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:$?
+
shell/ash_test/ash-redir/redir_to_bad_fd255.right+1 -1
@@ -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
shell/ash_test/ash-redir/redir_to_bad_fd3.right+1 -1
@@ -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
shell/hush.c+9 -4
@@ -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).
shell/hush_test/hush-redir/redir_exec2.right+4 -0
@@ -0,0 +1,4 @@
+fd/5
+fd/4
+fd/3
+One:1
shell/hush_test/hush-redir/redir_exec2.tests+11 -0
@@ -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:$?
+