| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- 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_ */
|