Re: stty sometimes hangs (ERESTARTSYS error) when called from .bashrc (cause discovered)

2008-07-06 Thread Joe Peterson
I have done more investigation, and I now know the cause of the
bash/stty problem.  It appears to be a race condition in bash (well,
between two different bash shells, actually).  I saw a post from a while
back about something similar by Ingo Molnar, so I have copied him here too.

Here is the ps tree of the test case where stty has hung:

 4704 ?S  0:00  \_ xterm
 4706 pts/3Ss 0:00  |   \_ -bash
 4739 pts/3S  0:00  |   \_ su
 4742 pts/3S  0:00  |   \_ bash
 4746 pts/3S+ 0:00  |   \_ su foo
 4747 pts/3S  0:00  |   \_ bash
 4752 pts/3T  0:00  |   \_ stty -ixany

What should happen is: when "su foo" (4746) is run, it spawns a bash
shell (4747) that then makes itself the session leader when it
initializes its job control.  The stty command (in the child bash's
.bashrc) will then be able to work (and not hang).

However, the hang happens when the parent bash (4742) interferes by
reverting the tty session leader back to its child (the "su foo"
process: 4746) shortly after the child bash (4747) becomes the leader.
The parent does this when it calls
execute_command_internal()->stop_pipeline()->give_terminal_to().  This
seems to happen at a slightly random time, making the issue intermittent
- it depends which one wins the race.

In summary, when the bug does *not* occur, here is the approximate
sequence (note I am :

1) parent bash (4742) runs 'su foo' (4746)
2) parent bash sets tty leader to 'su' (4746)
3) child bash (4747) initializes and sets itself to be the leader
4) stty command in .bashrc runs successfully

When the bug occurs, here is the sequence:

1) parent bash (4742) runs 'su foo' (4746)
2) child bash (4747) initializes and sets itself to be the leader
3) parent bash sets tty leader *back* to 'su' (4746)
4) stty command runs and fails/hangs because its parent is not leader

The various calls to tcsetpgrp() that do this are interleaved from the
two bash processes, and sometimes the parent does it slightly *after*
the child bash initializes job control - that's when the problem happens.

I have not looked further to find a solution (but it's a great start to
know the cause...!).  Any further help is welcome.

-Joe




Eval ${#name[subscript]} incorrect when having multibyte characters.

2008-07-06 Thread Wang Xin
Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linu
x-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/
local/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./incl
ude -I./lib   -g -O2
uname output: Linux shan 2.6.24.5-smp #2 SMP Wed Apr 30 13:41:38 CDT 2008 i686 I
ntel(R) Celeron(R) M processor 1.40GHz GenuineIntel GNU/Linux
Machine Type: i686-pc-linux-gnu

Bash Version: 3.2
Patch Level: 0
Release Status: release

Description:
When there are multibyte characters in an element of array, the
result of ${#name[subscript]} will be incorrect. It will be evaled
to numbers of bytes, but not numbers of characters.

Repeat-By:
This can be reproduced by:
1. a[0]=你好
2. echo ${#a[0]}

There are only two chinese characters, but the result is 6.

Fix:
Following patch may be helpful.

--- subst.c 2008-07-06 15:47:14.0 +0800
+++ bash-3.2/subst.c2008-07-06 15:47:39.0 +0800
@@ -4763,7 +4763,7 @@
   else
 t = (ind == 0) ? value_cell (var) : (char *)NULL;

-  len = STRLEN (t);
+  len = MB_STRLEN (t);
   return (len);
 }
 #endif /* ARRAY_VARS */