226 lines
6.9 KiB
Plaintext
226 lines
6.9 KiB
Plaintext
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'):
|
|
|
|
*** ../bash-4.3-patched/shell.c 2014-01-14 08:04:32.000000000 -0500
|
|
--- 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. */
|
|
*** ../bash-4.3-patched/builtins/read.def 2014-10-01 12:57:38.000000000 -0400
|
|
--- 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
|
|
--- 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 *));
|
|
*** ../bash-4.3-patched/bashline.c 2014-05-14 09:22:39.000000000 -0400
|
|
--- 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 ();
|
|
*** ../bash-4.3-patched/sig.c 2014-01-10 15:06:06.000000000 -0500
|
|
--- 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
|
|
*** ../bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
|
|
--- 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_ */
|