143 lines
5.2 KiB
Diff
143 lines
5.2 KiB
Diff
From 0390b4354a9e5df517ef2d4f9d78a099063b22b4 Mon Sep 17 00:00:00 2001
|
|
From: Chet Ramey <chet.ramey@case.edu>
|
|
Date: Tue, 28 Jan 2025 10:15:16 -0500
|
|
Subject: [PATCH] posix change for undoing redirections after failed exec;
|
|
change readline to set lines and columns after SIGTSTP/SIGCONT
|
|
|
|
Conflict:only the modified content of builtins/exec.def and execute_cmd.c is rounded.
|
|
|
|
---
|
|
builtins/exec.def | 11 +++++-----
|
|
execute_cmd.c | 56 +++++++++++++++++++++++++++++++----------------
|
|
2 files changed, 43 insertions(+), 24 deletions(-)
|
|
|
|
diff --git a/builtins/exec.def b/builtins/exec.def
|
|
index cbcb641..ee4921f 100644
|
|
--- a/builtins/exec.def
|
|
+++ b/builtins/exec.def
|
|
@@ -129,12 +129,13 @@ exec_builtin (list)
|
|
}
|
|
list = loptend;
|
|
|
|
- /* First, let the redirections remain. */
|
|
- dispose_redirects (redirection_undo_list);
|
|
- redirection_undo_list = (REDIRECT *)NULL;
|
|
-
|
|
+ /* First, let the redirections remain if exec is called without operands */
|
|
if (list == 0)
|
|
- return (EXECUTION_SUCCESS);
|
|
+ {
|
|
+ dispose_redirects (redirection_undo_list);
|
|
+ redirection_undo_list = (REDIRECT *)NULL;
|
|
+ return (EXECUTION_SUCCESS);
|
|
+ }
|
|
|
|
#if defined (RESTRICTED_SHELL)
|
|
if (restricted)
|
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
|
index 9adb9cb..82ad27d 100644
|
|
--- a/execute_cmd.c
|
|
+++ b/execute_cmd.c
|
|
@@ -5292,7 +5292,7 @@ execute_builtin_or_function (words, builtin, var, redirects,
|
|
struct fd_bitmap *fds_to_close;
|
|
int flags;
|
|
{
|
|
- int result;
|
|
+ int result, has_exec_redirects;
|
|
REDIRECT *saved_undo_list;
|
|
#if defined (PROCESS_SUBSTITUTION)
|
|
int ofifo, nfifo, osize;
|
|
@@ -5319,17 +5319,25 @@ execute_builtin_or_function (words, builtin, var, redirects,
|
|
return (EX_REDIRFAIL); /* was EXECUTION_FAILURE */
|
|
}
|
|
|
|
+ /* Is this the exec builtin with redirections? We want to undo them and
|
|
+ throw away the exec_redirection_undo_list if exec has a program name
|
|
+ argument, fails to execute it, and does not exit the shell */
|
|
+ has_exec_redirects = (builtin == exec_builtin) && redirection_undo_list;
|
|
+
|
|
saved_undo_list = redirection_undo_list;
|
|
|
|
/* Calling the "exec" builtin changes redirections forever. */
|
|
if (builtin == exec_builtin)
|
|
{
|
|
- dispose_redirects (saved_undo_list);
|
|
+ /* let exec_builtin handle disposing redirection_undo_list */
|
|
saved_undo_list = exec_redirection_undo_list;
|
|
exec_redirection_undo_list = (REDIRECT *)NULL;
|
|
}
|
|
else
|
|
- dispose_exec_redirects ();
|
|
+ {
|
|
+ dispose_exec_redirects ();
|
|
+ redirection_undo_list = (REDIRECT *)NULL;
|
|
+ }
|
|
|
|
if (saved_undo_list)
|
|
{
|
|
@@ -5337,8 +5345,6 @@ execute_builtin_or_function (words, builtin, var, redirects,
|
|
add_unwind_protect (cleanup_redirects, (char *)saved_undo_list);
|
|
}
|
|
|
|
- redirection_undo_list = (REDIRECT *)NULL;
|
|
-
|
|
if (builtin)
|
|
result = execute_builtin (builtin, words, flags, 0);
|
|
else
|
|
@@ -5350,26 +5356,38 @@ execute_builtin_or_function (words, builtin, var, redirects,
|
|
if (ferror (stdout))
|
|
clearerr (stdout);
|
|
|
|
- /* If we are executing the `command' builtin, but this_shell_builtin is
|
|
- set to `exec_builtin', we know that we have something like
|
|
- `command exec [redirection]', since otherwise `exec' would have
|
|
- overwritten the shell and we wouldn't get here. In this case, we
|
|
- want to behave as if the `command' builtin had not been specified
|
|
- and preserve the redirections. */
|
|
- if (builtin == command_builtin && this_shell_builtin == exec_builtin)
|
|
+ if (has_exec_redirects && redirection_undo_list)
|
|
{
|
|
- int discard;
|
|
-
|
|
- discard = 0;
|
|
+ /* We have returned from the exec builtin. If redirection_undo_list is
|
|
+ still non-null, we had an operand and failed to exit the shell for
|
|
+ some reason. We want to dispose of saved_undo_list, discard the frame,
|
|
+ and let the redirections be undone as usual. If redirection_undo_list
|
|
+ is NULL, then exec_builtin had no program name operand and disposed
|
|
+ of it. In that case, we should perform the redirections in
|
|
+ exec_redirection_undo_list (saved_undo_list) like usual. */
|
|
+ if (saved_undo_list)
|
|
+ {
|
|
+ dispose_redirects (saved_undo_list); /* exec_redirection_undo_list */
|
|
+ discard_unwind_frame ("saved-redirects");
|
|
+ }
|
|
+ saved_undo_list = exec_redirection_undo_list = (REDIRECT *)NULL;
|
|
+ }
|
|
+ /* This code is no longer executed and remains only for explanatory reasons. */
|
|
+ else if (builtin == command_builtin && this_shell_builtin == exec_builtin)
|
|
+ {
|
|
+ /* If we are executing the `command' builtin, but this_shell_builtin is
|
|
+ set to `exec_builtin', we know that we have something like
|
|
+ `command exec [redirection]', since otherwise `exec' would have
|
|
+ overwritten the shell and we wouldn't get here. In this case, we
|
|
+ want to behave as if the `command' builtin had not been specified
|
|
+ and preserve the redirections. */
|
|
if (saved_undo_list)
|
|
{
|
|
- dispose_redirects (saved_undo_list);
|
|
- discard = 1;
|
|
+ dispose_redirects (saved_undo_list); /* redirection_undo_list */
|
|
+ discard_unwind_frame ("saved-redirects");
|
|
}
|
|
redirection_undo_list = exec_redirection_undo_list;
|
|
saved_undo_list = exec_redirection_undo_list = (REDIRECT *)NULL;
|
|
- if (discard)
|
|
- discard_unwind_frame ("saved-redirects");
|
|
}
|
|
|
|
if (saved_undo_list)
|
|
--
|
|
2.33.0
|
|
|