bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bash-4.3 Official Patch 33


From: Chet Ramey
Subject: Bash-4.3 Official Patch 33
Date: Tue, 30 Dec 2014 09:13:46 -0500

                             BASH PATCH REPORT
                             =================

Bash-Release:   4.3
Patch-ID:       bash43-033

Bug-Reported-by:        address@hidden, Jan Rome <address@hidden>
Bug-Reference-ID:       <address@hidden>,
                        <address@hidden>
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_ */

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    address@hidden    http://cnswww.cns.cwru.edu/~chet/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]