|
@@ -0,0 +1,229 @@
|
|
|
+From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-033
|
|
|
+
|
|
|
+Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
|
|
+
|
|
|
+ BASH PATCH REPORT
|
|
|
+ =================
|
|
|
+
|
|
|
+Bash-Release: 4.3
|
|
|
+Patch-ID: bash43-033
|
|
|
+
|
|
|
+Bug-Reported-by: mickael9@gmail.com, Jan Rome <jan.rome@gmail.com>
|
|
|
+Bug-Reference-ID: <20140907224046.382ED3610CC@mickael-laptop.localdomain>,
|
|
|
+ <540D661D.50908@gmail.com>
|
|
|
+Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-09/msg00029.html
|
|
|
+ http://lists.gnu.org/archive/html/bug-bash/2014-09/msg00030.html
|
|
|
+
|
|
|
+Bug-Description:
|
|
|
+
|
|
|
+Bash does not clean up the terminal state in all cases where bash or
|
|
|
+readline modifies it and bash is subsequently terminated by a fatal signal.
|
|
|
+This happens when the `read' builtin modifies the terminal settings, both
|
|
|
+when readline is active and when it is not. It occurs most often when a script
|
|
|
+installs a trap that exits on a signal without re-sending the signal to itself.
|
|
|
+
|
|
|
+Patch (apply with `patch -p0'):
|
|
|
+
|
|
|
+*** a/bash-4.3-patched/shell.c 2014-01-14 08:04:32.000000000 -0500
|
|
|
+--- b/shell.c 2014-12-22 10:27:50.000000000 -0500
|
|
|
+***************
|
|
|
+*** 74,77 ****
|
|
|
+--- 74,78 ----
|
|
|
+
|
|
|
+ #if defined (READLINE)
|
|
|
++ # include <readline/readline.h>
|
|
|
+ # include "bashline.h"
|
|
|
+ #endif
|
|
|
+***************
|
|
|
+*** 910,913 ****
|
|
|
+--- 912,923 ----
|
|
|
+ fflush (stderr);
|
|
|
+
|
|
|
++ /* Clean up the terminal if we are in a state where it's been modified. */
|
|
|
++ #if defined (READLINE)
|
|
|
++ if (RL_ISSTATE (RL_STATE_TERMPREPPED) && rl_deprep_term_function)
|
|
|
++ (*rl_deprep_term_function) ();
|
|
|
++ #endif
|
|
|
++ if (read_tty_modified ())
|
|
|
++ read_tty_cleanup ();
|
|
|
++
|
|
|
+ /* Do trap[0] if defined. Allow it to override the exit status
|
|
|
+ passed to us. */
|
|
|
+*** a/bash-4.3-patched/builtins/read.def 2014-10-01 12:57:38.000000000 -0400
|
|
|
+--- b/builtins/read.def 2014-12-22 10:48:54.000000000 -0500
|
|
|
+***************
|
|
|
+*** 141,148 ****
|
|
|
+ int sigalrm_seen;
|
|
|
+
|
|
|
+! static int reading;
|
|
|
+ static SigHandler *old_alrm;
|
|
|
+ static unsigned char delim;
|
|
|
+
|
|
|
+ /* In all cases, SIGALRM just sets a flag that we check periodically. This
|
|
|
+ avoids problems with the semi-tricky stuff we do with the xfree of
|
|
|
+--- 141,150 ----
|
|
|
+ int sigalrm_seen;
|
|
|
+
|
|
|
+! static int reading, tty_modified;
|
|
|
+ static SigHandler *old_alrm;
|
|
|
+ static unsigned char delim;
|
|
|
+
|
|
|
++ static struct ttsave termsave;
|
|
|
++
|
|
|
+ /* In all cases, SIGALRM just sets a flag that we check periodically. This
|
|
|
+ avoids problems with the semi-tricky stuff we do with the xfree of
|
|
|
+***************
|
|
|
+*** 189,193 ****
|
|
|
+ SHELL_VAR *var;
|
|
|
+ TTYSTRUCT ttattrs, ttset;
|
|
|
+- struct ttsave termsave;
|
|
|
+ #if defined (ARRAY_VARS)
|
|
|
+ WORD_LIST *alist;
|
|
|
+--- 191,194 ----
|
|
|
+***************
|
|
|
+*** 222,226 ****
|
|
|
+ USE_VAR(lastsig);
|
|
|
+
|
|
|
+! sigalrm_seen = reading = 0;
|
|
|
+
|
|
|
+ i = 0; /* Index into the string that we are reading. */
|
|
|
+--- 223,227 ----
|
|
|
+ USE_VAR(lastsig);
|
|
|
+
|
|
|
+! sigalrm_seen = reading = tty_modified = 0;
|
|
|
+
|
|
|
+ i = 0; /* Index into the string that we are reading. */
|
|
|
+***************
|
|
|
+*** 439,442 ****
|
|
|
+--- 440,445 ----
|
|
|
+ goto assign_vars;
|
|
|
+ }
|
|
|
++ if (interactive_shell == 0)
|
|
|
++ initialize_terminating_signals ();
|
|
|
+ old_alrm = set_signal_handler (SIGALRM, sigalrm);
|
|
|
+ add_unwind_protect (reset_alarm, (char *)NULL);
|
|
|
+***************
|
|
|
+*** 483,487 ****
|
|
|
+--- 486,493 ----
|
|
|
+ if (i < 0)
|
|
|
+ sh_ttyerror (1);
|
|
|
++ tty_modified = 1;
|
|
|
+ add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
|
|
|
++ if (interactive_shell == 0)
|
|
|
++ initialize_terminating_signals ();
|
|
|
+ }
|
|
|
+ }
|
|
|
+***************
|
|
|
+*** 498,502 ****
|
|
|
+--- 504,511 ----
|
|
|
+ sh_ttyerror (1);
|
|
|
+
|
|
|
++ tty_modified = 1;
|
|
|
+ add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
|
|
|
++ if (interactive_shell == 0)
|
|
|
++ initialize_terminating_signals ();
|
|
|
+ }
|
|
|
+
|
|
|
+***************
|
|
|
+*** 589,592 ****
|
|
|
+--- 598,603 ----
|
|
|
+ else
|
|
|
+ lastsig = 0;
|
|
|
++ if (terminating_signal && tty_modified)
|
|
|
++ ttyrestore (&termsave); /* fix terminal before exiting */
|
|
|
+ CHECK_TERMSIG;
|
|
|
+ eof = 1;
|
|
|
+***************
|
|
|
+*** 979,982 ****
|
|
|
+--- 990,1007 ----
|
|
|
+ {
|
|
|
+ ttsetattr (ttp->fd, ttp->attrs);
|
|
|
++ tty_modified = 0;
|
|
|
++ }
|
|
|
++
|
|
|
++ void
|
|
|
++ read_tty_cleanup ()
|
|
|
++ {
|
|
|
++ if (tty_modified)
|
|
|
++ ttyrestore (&termsave);
|
|
|
++ }
|
|
|
++
|
|
|
++ int
|
|
|
++ read_tty_modified ()
|
|
|
++ {
|
|
|
++ return (tty_modified);
|
|
|
+ }
|
|
|
+
|
|
|
+*** ./bash-4.3-patched/builtins/common.h 2014-10-01 12:57:47.000000000 -0400
|
|
|
+--- b/builtins/common.h 2014-12-22 10:10:14.000000000 -0500
|
|
|
+***************
|
|
|
+*** 123,126 ****
|
|
|
+--- 141,148 ----
|
|
|
+ extern void getopts_reset __P((int));
|
|
|
+
|
|
|
++ /* Functions from read.def */
|
|
|
++ extern void read_tty_cleanup __P((void));
|
|
|
++ extern int read_tty_modified __P((void));
|
|
|
++
|
|
|
+ /* Functions from set.def */
|
|
|
+ extern int minus_o_option_value __P((char *));
|
|
|
+*** a/bash-4.3-patched/bashline.c 2014-05-14 09:22:39.000000000 -0400
|
|
|
+--- b/bashline.c 2014-09-08 11:28:56.000000000 -0400
|
|
|
+***************
|
|
|
+*** 203,206 ****
|
|
|
+--- 203,207 ----
|
|
|
+ extern int array_needs_making;
|
|
|
+ extern int posixly_correct, no_symbolic_links;
|
|
|
++ extern int sigalrm_seen;
|
|
|
+ extern char *current_prompt_string, *ps1_prompt;
|
|
|
+ extern STRING_INT_ALIST word_token_alist[];
|
|
|
+***************
|
|
|
+*** 4209,4214 ****
|
|
|
+ /* If we're going to longjmp to top_level, make sure we clean up readline.
|
|
|
+ check_signals will call QUIT, which will eventually longjmp to top_level,
|
|
|
+! calling run_interrupt_trap along the way. */
|
|
|
+! if (interrupt_state)
|
|
|
+ rl_cleanup_after_signal ();
|
|
|
+ bashline_reset_event_hook ();
|
|
|
+--- 4262,4268 ----
|
|
|
+ /* If we're going to longjmp to top_level, make sure we clean up readline.
|
|
|
+ check_signals will call QUIT, which will eventually longjmp to top_level,
|
|
|
+! calling run_interrupt_trap along the way. The check for sigalrm_seen is
|
|
|
+! to clean up the read builtin's state. */
|
|
|
+! if (terminating_signal || interrupt_state || sigalrm_seen)
|
|
|
+ rl_cleanup_after_signal ();
|
|
|
+ bashline_reset_event_hook ();
|
|
|
+*** a/bash-4.3-patched/sig.c 2014-01-10 15:06:06.000000000 -0500
|
|
|
+--- b/sig.c 2014-09-08 11:26:33.000000000 -0400
|
|
|
+***************
|
|
|
+*** 533,538 ****
|
|
|
+ /* Set the event hook so readline will call it after the signal handlers
|
|
|
+ finish executing, so if this interrupted character input we can get
|
|
|
+! quick response. */
|
|
|
+! if (interactive_shell && interactive && no_line_editing == 0)
|
|
|
+ bashline_set_event_hook ();
|
|
|
+ #endif
|
|
|
+--- 533,540 ----
|
|
|
+ /* Set the event hook so readline will call it after the signal handlers
|
|
|
+ finish executing, so if this interrupted character input we can get
|
|
|
+! quick response. If readline is active or has modified the terminal we
|
|
|
+! need to set this no matter what the signal is, though the check for
|
|
|
+! RL_STATE_TERMPREPPED is possibly redundant. */
|
|
|
+! if (RL_ISSTATE (RL_STATE_SIGHANDLER) || RL_ISSTATE (RL_STATE_TERMPREPPED))
|
|
|
+ bashline_set_event_hook ();
|
|
|
+ #endif
|
|
|
+*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
|
|
|
+--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
|
|
|
+***************
|
|
|
+*** 26,30 ****
|
|
|
+ looks for to find the patch level (for the sccs version string). */
|
|
|
+
|
|
|
+! #define PATCHLEVEL 32
|
|
|
+
|
|
|
+ #endif /* _PATCHLEVEL_H_ */
|
|
|
+--- 26,30 ----
|
|
|
+ looks for to find the patch level (for the sccs version string). */
|
|
|
+
|
|
|
+! #define PATCHLEVEL 33
|
|
|
+
|
|
|
+ #endif /* _PATCHLEVEL_H_ */
|