1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
Index: redir.c
===================================================================
--- redir.c.orig
+++ redir.c
@@ -176,12 +176,13 @@ redirection_error (temp, error)
how to undo the redirections later, if non-zero. If flags & RX_CLEXEC
is non-zero, file descriptors opened in do_redirection () have their
close-on-exec flag set. */
+static int close_before_dup2_err;
int
do_redirections (list, flags)
REDIRECT *list;
int flags;
{
- int error;
+ int error, ret = 0;
REDIRECT *temp;
if (flags & RX_UNDOABLE)
@@ -197,14 +198,21 @@ do_redirections (list, flags)
for (temp = list; temp; temp = temp->next)
{
+ close_before_dup2_err = 0;
error = do_redirection_internal (temp, flags);
if (error)
{
redirection_error (temp, error);
return (error);
}
+ if (close_before_dup2_err)
+ {
+ redirection_error (temp, close_before_dup2_err);
+ ret = close_before_dup2_err;
+ }
}
- return (0);
+
+ return (ret);
}
/* Return non-zero if the redirection pointed to by REDIRECT has a
@@ -786,6 +794,8 @@ do_redirection_internal (redirect, flags
#if defined (BUFFERED_INPUT)
check_bash_input (redirector);
#endif
+ if ((fd != redirector) && (close(redirector) < 0) && (errno != EBADF))
+ close_before_dup2_err = errno;
/* Make sure there is no pending output before we change the state
of the underlying file descriptor, since the builtins use stdio
@@ -879,6 +889,9 @@ do_redirection_internal (redirect, flags
#if defined (BUFFERED_INPUT)
check_bash_input (redirector);
#endif
+ if ((fd != redirector) && (close(redirector) < 0) && (errno != EBADF))
+ close_before_dup2_err = errno;
+
if (fd != redirector && dup2 (fd, redirector) < 0)
{
r = errno;
@@ -920,6 +933,9 @@ do_redirection_internal (redirect, flags
#if defined (BUFFERED_INPUT)
check_bash_input (redirector);
#endif
+ if ((close(redirector) < 0) && (errno != EBADF))
+ close_before_dup2_err = errno;
+
/* This is correct. 2>&1 means dup2 (1, 2); */
if (dup2 (redir_fd, redirector) < 0)
return (errno);
Index: execute_cmd.c
===================================================================
--- execute_cmd.c.orig
+++ execute_cmd.c
@@ -121,7 +121,7 @@ static void close_pipes __P((int, int));
static void do_piping __P((int, int));
static void bind_lastarg __P((char *));
static int shell_control_structure __P((enum command_type));
-static void cleanup_redirects __P((REDIRECT *));
+static int cleanup_redirects __P((REDIRECT *));
#if defined (JOB_CONTROL)
static int restore_signal_mask __P((sigset_t *));
@@ -417,12 +417,13 @@ shell_control_structure (type)
/* A function to use to unwind_protect the redirection undo list
for loops. */
-static void
+static int
cleanup_redirects (list)
REDIRECT *list;
{
- do_redirections (list, RX_ACTIVE);
+ int ret = do_redirections (list, RX_ACTIVE);
dispose_redirects (list);
+ return (ret ? 1 : 0);
}
#if 0
@@ -664,7 +665,7 @@ execute_command_internal (command, async
redirection.) */
if (do_redirections (command->redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
{
- cleanup_redirects (redirection_undo_list);
+ (void)cleanup_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
dispose_exec_redirects ();
return (last_command_exit_value = EXECUTION_FAILURE);
@@ -3314,7 +3315,7 @@ execute_null_command (redirects, pipe_in
REDIRECT *redirects;
int pipe_in, pipe_out, async;
{
- int r;
+ int r, s;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
{
@@ -3361,10 +3362,10 @@ execute_null_command (redirects, pipe_in
substitution. Otherwise, return EXECUTION_SUCCESS. */
r = do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE);
- cleanup_redirects (redirection_undo_list);
+ s = cleanup_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
- if (r != 0)
+ if (r != 0 || s != 0)
return (EXECUTION_FAILURE);
else if (last_command_subst_pid != NO_PID)
return (last_command_exit_value);
@@ -4238,7 +4239,7 @@ execute_builtin_or_function (words, buil
if (do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
{
- cleanup_redirects (redirection_undo_list);
+ (void)cleanup_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
dispose_exec_redirects ();
return (EX_REDIRFAIL); /* was EXECUTION_FAILURE */
@@ -4299,8 +4300,10 @@ execute_builtin_or_function (words, buil
if (redirection_undo_list)
{
- cleanup_redirects (redirection_undo_list);
+ int ret = cleanup_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
+ if (result == 0)
+ result = ret;
}
return (result);
|