2009-08-28 17:45:57 +02:00
|
|
|
Index: redir.c
|
|
|
|
===================================================================
|
|
|
|
--- redir.c.orig
|
|
|
|
+++ redir.c
|
|
|
|
@@ -176,12 +176,13 @@ redirection_error (temp, error)
|
2006-12-15 18:03:59 +01:00
|
|
|
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)
|
2009-08-28 17:45:57 +02:00
|
|
|
@@ -197,14 +198,21 @@ do_redirections (list, flags)
|
2006-12-15 18:03:59 +01:00
|
|
|
|
|
|
|
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
|
2009-08-28 17:45:57 +02:00
|
|
|
@@ -786,6 +794,8 @@ do_redirection_internal (redirect, flags
|
2006-12-15 18:03:59 +01:00
|
|
|
#if defined (BUFFERED_INPUT)
|
|
|
|
check_bash_input (redirector);
|
|
|
|
#endif
|
|
|
|
+ if ((fd != redirector) && (close(redirector) < 0) && (errno != EBADF))
|
|
|
|
+ close_before_dup2_err = errno;
|
|
|
|
|
2009-08-28 17:45:57 +02:00
|
|
|
/* 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
|
2006-12-15 18:03:59 +01:00
|
|
|
#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;
|
2009-08-28 17:45:57 +02:00
|
|
|
@@ -920,6 +933,9 @@ do_redirection_internal (redirect, flags
|
2006-12-15 18:03:59 +01:00
|
|
|
#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);
|
2009-08-28 17:45:57 +02:00
|
|
|
Index: execute_cmd.c
|
|
|
|
===================================================================
|
|
|
|
--- execute_cmd.c.orig
|
|
|
|
+++ execute_cmd.c
|
|
|
|
@@ -121,7 +121,7 @@ static void close_pipes __P((int, int));
|
2006-12-15 18:03:59 +01:00
|
|
|
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 *));
|
2009-08-28 17:45:57 +02:00
|
|
|
@@ -417,12 +417,13 @@ shell_control_structure (type)
|
2006-12-15 18:03:59 +01:00
|
|
|
|
|
|
|
/* 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
|
2009-08-28 17:45:57 +02:00
|
|
|
@@ -664,7 +665,7 @@ execute_command_internal (command, async
|
2006-12-15 18:03:59 +01:00
|
|
|
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 ();
|
2009-08-28 17:45:57 +02:00
|
|
|
return (last_command_exit_value = EXECUTION_FAILURE);
|
|
|
|
@@ -3314,7 +3315,7 @@ execute_null_command (redirects, pipe_in
|
|
|
|
REDIRECT *redirects;
|
2006-12-15 18:03:59 +01:00
|
|
|
int pipe_in, pipe_out, async;
|
|
|
|
{
|
|
|
|
- int r;
|
|
|
|
+ int r, s;
|
|
|
|
|
|
|
|
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
|
|
|
|
{
|
2009-08-28 17:45:57 +02:00
|
|
|
@@ -3361,10 +3362,10 @@ execute_null_command (redirects, pipe_in
|
2006-12-15 18:03:59 +01:00
|
|
|
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);
|
2009-08-28 17:45:57 +02:00
|
|
|
else if (last_command_subst_pid != NO_PID)
|
2006-12-15 18:03:59 +01:00
|
|
|
return (last_command_exit_value);
|
2009-08-28 17:45:57 +02:00
|
|
|
@@ -4238,7 +4239,7 @@ execute_builtin_or_function (words, buil
|
2006-12-15 18:03:59 +01:00
|
|
|
|
|
|
|
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 */
|
2009-08-28 17:45:57 +02:00
|
|
|
@@ -4299,8 +4300,10 @@ execute_builtin_or_function (words, buil
|
2006-12-15 18:03:59 +01:00
|
|
|
|
|
|
|
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);
|