Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/local/share/locale' -DPACKAGE='bash' 
-DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib   -g -O2
uname output: Linux tjanouse.englab.brq.redhat.com 2.6.18-8.1.8.el5 #1 SMP Mon 
Jun 25 17:06:19 EDT 2007 i686 i686 i386 GNU/Linux
Machine Type: i686-pc-linux-gnu

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

Description:
        If you cause rng to be seeded in a subshell (enclose the command in
        parentheses) and in this same subshell spawn another subshell, rng is
        not seeded as it should be. See the example in Repeat-by.

Repeat-By:
        $ ( echo $RANDOM; ( echo $RANDOM ); ( echo $RANDOM ) )
        28804
        3664
        3664

Fix:
        We had a fix in the Fedora package that used subshell_level instead of
        just looking at subshell_environment, but that introduced another
        oddity, since subshell_level is not increased for simple async
        commands.
        (bugzilla for this one is
        https://bugzilla.redhat.com/show_bug.cgi?id=344411 )

        I'm attaching a patch that was applied over that one, so it just shows
        what the final solution is like, it's not applicable to 3.2 tarball.

-- 
Tomas Janousek, SW Engineer, Red Hat, Inc.
344411: $RANDOM stays the same when job executed in the background

In bash 3.0, random was seeded whenever subshell_environment != 0.

In bash 3.2, random was seeded whenever subshell_environment != 0 &&
seeded_subshell == 0. And when it was seeded, seeded_subshell was set to 1.

Therefore, in 3.2, if you seeded random in a subshell and in this subshell
invoked another one, it wasn't reseeded as it should have been. A testcase for
that is this:
    ( echo $RANDOM; ( echo $RANDOM ); ( echo $RANDOM ) )

Tomas's patch (bash-3.2-rng.patch) changed the code to use subshell_level.
subshell_level is not increased for simple async commands, however. So,
although he fixed the previous case, he introduced another. Here's a testcase:
    echo $RANDOM; echo $RANDOM & echo $RANDOM &

I decided to just compare the pids, that should be safe enough.

Written-by: Tomas Janousek <[EMAIL PROTECTED]>
Reviewed-by: Tomas Mraz <[EMAIL PROTECTED]>

--- bash-3.2/variables.c.344411 2007-11-06 19:26:42.000000000 +0100
+++ bash-3.2/variables.c        2007-11-06 20:27:25.000000000 +0100
@@ -1211,7 +1211,7 @@
      arrayind_t unused;
 {
   sbrand ((unsigned int)strtoul (value, (char **)NULL, 10));
-  seeded_subshell = subshell_level;
+  seeded_subshell = getpid();
   return (self);
 }
 
@@ -1221,10 +1221,10 @@
   int rv;
 
   /* Reset for command and process substitution. */
-  if (seeded_subshell < subshell_level)
+  if (seeded_subshell != getpid())
     {
       seed_random ();
-      seeded_subshell = subshell_level;
+      seeded_subshell = getpid();
     }
 
   do

Reply via email to