bash-3.2: Bad signal work in readline

2009-01-19 Thread Roman Rakus
It's possible to make bash locked up. It's done by bad signal handling 
in bash and/or readline. It may happened when bash/readline catch signal 
in any alloc call. I have changed readline to process signals only in 
safe point. This appears also in bash-4. I will attach a small 
reproducer (normally it's nearly impossible to reproduce this bug. With 
this reproducer patch you can hit ctrl-r and then ctrl-c to see bash 
locked up) and patch which fix this bug.
--- bash-3.2/lib/readline/isearch.c-orig	2009-01-09 08:08:05.0 +0100
+++ bash-3.2/lib/readline/isearch.c	2009-01-09 08:17:00.0 +0100
@@ -220,7 +220,9 @@ _rl_isearch_init (direction)
 
   /* Allocate space for this many lines, +1 for the current input line,
  and remember those lines. */
+{int xc; cxt->lines = NULL; for (xc = 0; xc < 3000; xc++) { xfree (cxt->lines);
   cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
+}}
   for (i = 0; i < cxt->hlen; i++)
 cxt->lines[i] = hlist[i]->line;
 
diff -up bash-3.2/lib/readline/signals.c.rr bash-3.2/lib/readline/signals.c
--- bash-3.2/lib/readline/signals.c.rr	2009-01-19 15:57:29.0 +0100
+++ bash-3.2/lib/readline/signals.c	2009-01-19 16:00:04.0 +0100
@@ -111,11 +111,19 @@ static sighandler_cxt old_winch;
 #endif
 
 /* Readline signal handler functions. */
+int catched_signal = 0;
 
 static RETSIGTYPE
 rl_signal_handler (sig)
  int sig;
 {
+  catched_signal = sig;
+  SIGHANDLER_RETURN;
+}
+
+void do_rl_signal_handler (sig)
+{
+  catched_signal = 0;
 #if defined (HAVE_POSIX_SIGNALS)
   sigset_t set;
 #else /* !HAVE_POSIX_SIGNALS */
@@ -192,7 +200,6 @@ rl_signal_handler (sig)
 }
 
   RL_UNSETSTATE(RL_STATE_SIGHANDLER);
-  SIGHANDLER_RETURN;
 }
 
 #if defined (SIGWINCH)
diff -up bash-3.2/lib/readline/readline.h.rr bash-3.2/lib/readline/readline.h
--- bash-3.2/lib/readline/readline.h.rr	2009-01-19 15:57:38.0 +0100
+++ bash-3.2/lib/readline/readline.h	2009-01-19 15:58:35.0 +0100
@@ -428,6 +428,16 @@ extern int rl_clear_signals PARAMS((void
 extern void rl_cleanup_after_signal PARAMS((void));
 extern void rl_reset_after_signal PARAMS((void));
 extern void rl_free_line_state PARAMS((void));
+extern void do_rl_signal_handler (int);
+extern int catched_signal;
+#define CATCH_SIGNALS() \
+  do\
+{   \
+  if (catched_signal)   \
+do_rl_signal_handler (catched_signal);  \
+} while (0)
+
+
  
 extern int rl_set_paren_blink_timeout PARAMS((int));
 
diff -up bash-3.2/lib/readline/input.c.rr bash-3.2/lib/readline/input.c
--- bash-3.2/lib/readline/input.c.rr	2009-01-19 15:57:44.0 +0100
+++ bash-3.2/lib/readline/input.c	2009-01-19 16:00:33.0 +0100
@@ -465,6 +465,7 @@ rl_getc (stream)
 
   while (1)
 {
+  CATCH_SIGNALS ();
 #if defined (__MINGW32__)
   if (isatty (fileno (stream)))
 	return (getch ());


Re: bash-3.2: Bad signal work in readline

2009-01-19 Thread Andreas Schwab
Roman Rakus  writes:

> diff -up bash-3.2/lib/readline/signals.c.rr bash-3.2/lib/readline/signals.c
> --- bash-3.2/lib/readline/signals.c.rr2009-01-19 15:57:29.0 
> +0100
> +++ bash-3.2/lib/readline/signals.c   2009-01-19 16:00:04.0 +0100
> @@ -111,11 +111,19 @@ static sighandler_cxt old_winch;
>  #endif
>  
>  /* Readline signal handler functions. */
> +int catched_signal = 0;

That needs to be volatile sig_atomic_t.

Andreas.

-- 
Andreas Schwab, SuSE Labs, sch...@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."




simple bug/compat question

2009-01-19 Thread Linda Walsh

Am running an older bash version and this may be fixed (assuming it
is a bug and I'm not confused...:-))

bash version = 3.2.39(20)

This works:
1)  if [  -n ""  -a 2 -gt 1 ] ; then echo one;fi

This does not:
2)  if [[  -n ""  -a 2 -gt 1 ]] ; then echo one;fi



Shouldn't 2 work equally well as 1?

(original test on "$1":
-n "$1" -a "$1" -gt 0
)





Re: simple bug/compat question

2009-01-19 Thread Jan Schampera
Linda Walsh wrote:
> Am running an older bash version and this may be fixed (assuming it
> is a bug and I'm not confused...:-))
> 
> bash version = 3.2.39(20)
> 
> This works:
> 1)if [  -n ""  -a 2 -gt 1 ] ; then echo one;fi
> 
> This does not:
> 2)if [[  -n ""  -a 2 -gt 1 ]] ; then echo one;fi
> 
> 
> 
> Shouldn't 2 work equally well as 1?
> 
> (original test on "$1":
> -n "$1" -a "$1" -gt 0
> )

I don't know if it should be line that, but it definitely isn't the
case. This is also (indirectly) described in the manual: There's a
section about "conditional expressions" which holds all the stuff that [
and [[ have in common, then there are individual sections for [[ and
test ([) which list &&/|| for [[ and -a/-o for test.

http://bash-hackers.org/wiki/doku.php/syntax/ccmd/conditional_expression
/-
Do not use the test-typical operators -a and -o for AND and OR, they are
not known to the conditional expression. Instead, use the operators &&
and ||.
\-


Ragards,
Jan

-- 
This is my life - this is my net!
- Jan