diff -up bash-3.2/config.h.in.rng.patch bash-3.2/config.h.in --- bash-3.2/config.h.in.rng.patch 2007-08-20 13:42:49.000000000 +0200 +++ bash-3.2/config.h.in 2007-08-20 13:42:49.000000000 +0200 @@ -203,6 +203,8 @@ #define DEFAULT_MAIL_DIRECTORY "/var/spool/mail" +#undef PATH_RANDOMDEV + /* Characteristics of the system's header files and libraries that affect the compilation environment. */ @@ -817,6 +819,10 @@ /* Define if you have the wcwidth function. */ #undef HAVE_WCWIDTH +#undef HAVE_RANDOM + +#undef HAVE_SRANDOM + /* Presence of certain system include files. */ /* Define if you have the header file. */ diff -up bash-3.2/configure.in.rng.patch bash-3.2/configure.in --- bash-3.2/configure.in.rng.patch 2007-08-20 13:42:49.000000000 +0200 +++ bash-3.2/configure.in 2007-08-20 13:42:49.000000000 +0200 @@ -111,6 +111,7 @@ AC_ARG_WITH(gnu-malloc, AC_HELP_STRING([ AC_ARG_WITH(installed-readline, AC_HELP_STRING([--with-installed-readline], [use a version of the readline library that is already installed]), opt_with_installed_readline=$withval) AC_ARG_WITH(purecov, AC_HELP_STRING([--with-purecov], [configure to postprocess with pure coverage]), opt_purecov=$withval) AC_ARG_WITH(purify, AC_HELP_STRING([--with-purify], [configure to postprocess with purify]), opt_purify=$withval) +AC_ARG_WITH(random, AC_HELP_STRING([--with-randomdev=path], [use specified random device instead of /dev/urandom]), opt_randomdev=$withval) if test "$opt_bash_malloc" = yes; then MALLOC_TARGET=malloc @@ -152,6 +153,15 @@ if test -z "${DEBUGGER_START_FILE}"; the DEBUGGER_START_FILE=${ac_default_prefix}/share/bashdb/bashdb-main.inc fi +if test "$opt_randomdev" = yes -o -z "$opt_randomdev"; then + opt_randomdev="/dev/urandom" +elif test "$opt_randomdev" = no; then + opt_randomdev= +fi +if test -n "$opt_randomdev"; then + AC_DEFINE_UNQUOTED(PATH_RANDOMDEV, "$opt_randomdev", [Random device path.]) +fi + dnl optional shell features in config.h.in opt_minimal_config=no @@ -708,6 +718,8 @@ AC_CHECK_FUNCS(bcopy bzero confstr fnmat setenv setlinebuf setlocale setvbuf siginterrupt strchr \ sysconf tcgetattr times ttyname tzset unsetenv) +AC_CHECK_FUNCS(random srandom) + AC_CHECK_FUNCS(vsnprintf snprintf vasprintf asprintf) AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit) AC_CHECK_FUNCS(getpwent getpwnam getpwuid) diff -up bash-3.2/variables.c.rng.patch bash-3.2/variables.c --- bash-3.2/variables.c.rng.patch 2006-09-08 19:33:32.000000000 +0200 +++ bash-3.2/variables.c 2007-08-20 16:16:56.000000000 +0200 @@ -42,6 +42,11 @@ #include "bashansi.h" #include "bashintl.h" +#if defined (PATH_RANDOMDEV) +# include +# include "filecntl.h" +#endif + #include "shell.h" #include "flags.h" #include "execute_cmd.h" @@ -182,7 +187,8 @@ static SHELL_VAR *get_seconds __P((SHELL static SHELL_VAR *init_seconds_var __P((void)); static int brand __P((void)); -static void sbrand __P((unsigned long)); /* set bash random number generator. */ +static void sbrand __P((unsigned int)); /* set bash random number generator. */ +static void seed_random __P((void)); /* seed the generator randomly */ static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t)); static SHELL_VAR *get_random __P((SHELL_VAR *)); @@ -494,9 +500,6 @@ initialize_shell_variables (env, privmod } #endif /* HISTORY */ - /* Seed the random number generator. */ - sbrand (dollar_dollar_pid + shell_start_time); - /* Handle some "special" variables that we may have inherited from a parent shell. */ if (interactive_shell) @@ -1143,9 +1146,11 @@ init_seconds_var () } /* The random number seed. You can change this by setting RANDOM. */ +#if !defined (HAVE_RANDOM) static unsigned long rseed = 1; +#endif static int last_random_value; -static int seeded_subshell = 0; +static int seeded_subshell = -1; /* A linear congruential random number generator based on the example one in the ANSI C standard. This one isn't very good, but a more @@ -1155,28 +1160,58 @@ static int seeded_subshell = 0; static int brand () { +#if defined (HAVE_RANDOM) + unsigned int rseed; + rseed = random(); +#else rseed = rseed * 1103515245 + 12345; +#endif return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */ } /* Set the random number generator seed to SEED. */ static void sbrand (seed) - unsigned long seed; + unsigned int seed; { +#if defined (HAVE_RANDOM) + srandom((unsigned int)seed); +#else rseed = seed; +#endif last_random_value = 0; } +static void +seed_random () +{ + unsigned int seed; +#if defined (PATH_RANDOMDEV) + int fd; + int rv; + if ((rv = fd = open (PATH_RANDOMDEV, O_RDONLY)) != -1) { + while ((rv = read(fd, &seed, sizeof(seed))) != sizeof(seed) && errno == EINTR); + close (fd); + } + if (rv != sizeof(seed)) { +#endif + struct timeval tv; + gettimeofday(&tv, NULL); + seed = (unsigned int)tv.tv_sec + (unsigned int)tv.tv_usec + getpid(); +#if defined (PATH_RANDOMDEV) + } +#endif + sbrand (seed); +} + static SHELL_VAR * assign_random (self, value, unused) SHELL_VAR *self; char *value; arrayind_t unused; { - sbrand (strtoul (value, (char **)NULL, 10)); - if (subshell_environment) - seeded_subshell = 1; + sbrand ((unsigned int)strtoul (value, (char **)NULL, 10)); + seeded_subshell = subshell_level; return (self); } @@ -1186,10 +1221,10 @@ get_random_number () int rv; /* Reset for command and process substitution. */ - if (subshell_environment && seeded_subshell == 0) + if (seeded_subshell < subshell_level) { - sbrand (rseed + getpid() + NOW); - seeded_subshell = 1; + seed_random (); + seeded_subshell = subshell_level; } do