wrap_offset if the text we're drawing begins before the last
invisible character in the line. Similar to fix from 5/24. Fixes
bug reported by Miroslav Lichvar <mlichvar@redhat.com>
+
+ 11/14
+ -----
+subst.c
+ - fix $[ expansion case to deal with extract_arithmetic_subst
+ returning NULL (if the `]' is missing) and return the construct
+ unchanged in that case. Fixes tab completion bug reported by
+ Heikki Hokkanen <hoxu@users.sf.net> (debian bug 451263)
+
+lib/readline/mbutil.c
+ - fix _rl_find_next_mbchar_internal to deal with invalid multibyte
+ character sequences when finding non-zero-length chars. Fixes
+ bug reported by Morita Sho <morita-pub-en-debian@inz.sakura.ne.jp>
+
+ 11/15
+ -----
+variables.c
+ - add new function `seedrand' to seed the bash random number
+ generator from more random data. Suggestion from Steve Grubb
+ <sgrubb@redhat.com>
+ - replace the rng in brand() with a slightly better one from FreeBSD
+ (filtered through Mac OS X 10.5). Replacement suggested by
+ Steve Grubb <sgrubb@redhat.com>
multibyte support functions). Fixes bug reported by Rich
Felker <dalias@aerifal.cx>
+ 11/5
+ ----
+execute_cmd.c
+ - if redirections attached to a compound command fail, make sure to
+ set last_command_exit_value when returning EXECUTION_FAILURE.
+ Fixes bug reported separately by Andreas Schwab <schwab@suse.de>
+ and Paul Eggert <eggert@cs.ucla.edu>
+
11/9
----
builtins/read.def
wrap_offset if the text we're drawing begins before the last
invisible character in the line. Similar to fix from 5/24. Fixes
bug reported by Miroslav Lichvar <mlichvar@redhat.com>
+
+ 11/14
+ -----
+subst.c
+ - fix $[ expansion case to deal with extract_arithmetic_subst
+ returning NULL (if the `]' is missing) and return the construct
+ unchanged in that case. Fixes tab completion bug reported by
+ Heikki Hokkanen <hoxu@users.sf.net> (debian bug 451263)
+
+lib/readline/display.c
+ - fix _rl_find_next_mbchar_internal to deal with invalid multibyte
+ character sequences when finding non-zero-length chars. Fixes
+ bug reported by Morita Sho <morita-pub-en-debian@inz.sakura.ne.jp>
+
+ 11/15
+ -----
+variables.c
+ - add new function `seedrand' to seed the bash random number
+ generator from more random data. Suggestion from Steve Grubb
+ <sgrubb@redhat.com>
+ - replace the rng in brand() with a slightly better one from FreeBSD
+ (filtered through Mac OS X 10.5). Replacement suggested by
+ Steve Grubb <sgrubb@redhat.com>
This file is cd.def, from which is created cd.c. It implements the
builtins "cd" and "pwd" in Bash.
-Copyright (C) 1987-2005 Free Software Foundation, Inc.
+Copyright (C) 1987-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
extern int posixly_correct;
extern int array_needs_making;
-extern char *bash_getcwd_errstr;
+extern const char * const bash_getcwd_errstr;
static int bindpwd __P((int));
static void setpwd __P((char *));
int no_symlinks;
{
char *dirname, *pwdvar;
- int old_anm;
+ int old_anm, r;
SHELL_VAR *tvar;
+ r = sh_chkwrite (EXECUTION_SUCCESS);
+
#define tcwd the_current_working_directory
dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
: get_working_directory ("cd");
if (dirname && dirname != the_current_working_directory)
free (dirname);
- return (EXECUTION_SUCCESS);
+ return (r);
}
/* Call get_working_directory to reset the value of
setpwd (directory);
if (directory != the_current_working_directory)
free (directory);
- fflush (stdout);
- if (ferror (stdout))
- {
- sh_wrerror ();
- clearerr (stdout);
- return (EXECUTION_FAILURE);
- }
-
- return (EXECUTION_SUCCESS);
+ return (sh_chkwrite (EXECUTION_SUCCESS));
}
else
return (EXECUTION_FAILURE);
#if defined (HANDLE_MULTIBYTE)
slen = strlen (garglist->word->word+1);
- mblength = mbrlen (garglist->word->word+1, slen, NULL);
-#if 0
+ mblength = MBLEN (garglist->word->word+1, slen);
if (mblength > 1)
-#else
- if (1)
-#endif
{
- mblength = mbrtowc (&wc, garglist->word->word+1, slen, NULL);
+ mblength = mbtowc (&wc, garglist->word->word+1, slen);
ch = wc; /* XXX */
}
else
#endif
- ch = garglist->word->word[1];
+ ch = (unsigned char)garglist->word->word[1];
garglist = garglist->next;
return (ch);
if (find_non_zero)
{
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
- while (tmp > 0 && wcwidth (wc) == 0)
+ while (MB_NULLWCH (tmp) == 0 && MB_INVALIDCH (tmp) == 0 && wcwidth (wc) == 0)
{
point += tmp;
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
- if (MB_NULLWCH (tmp) || MB_INVALIDCH (tmp))
- break;
}
}
return seed;
point = seed + _rl_adjust_point (string, seed, &ps);
- /* if this is true, means that seed was not pointed character
- started byte. So correct the point and consume count */
+ /* if this is true, means that seed was not pointing to a byte indicating
+ the beginning of a multibyte character. Correct the point and consume
+ one char. */
if (seed < point)
count--;
tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
if (MB_INVALIDCH ((size_t)tmp))
{
- /* invalid bytes. asume a byte represents a character */
+ /* invalid bytes. assume a byte represents a character */
point++;
count--;
/* reset states. */
if (find_non_zero)
{
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
- while (tmp > 0 && wcwidth (wc) == 0)
+ while (MB_NULLWCH (tmp) == 0 && MB_INVALIDCH (tmp) == 0 && wc_width (wc) == 0)
{
point += tmp;
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
- if (MB_NULLWCH (tmp) || MB_INVALIDCH (tmp))
- break;
}
}
t_index = zindex + 1;
temp = extract_arithmetic_subst (string, &t_index);
zindex = t_index;
+ if (temp == 0)
+ {
+ temp = savestring (string);
+ if (expanded_something)
+ *expanded_something = 0;
+ goto return0;
+ }
/* Do initial variable expansion. */
temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
0
./arith.tests: line 149: 7 = 43 : attempted assignment to non-variable (error token is "= 43 ")
./arith.tests: line 150: 2#44: value too great for base (error token is "2#44")
-./arith.tests: line 151: 44 / 0 : division by 0 (error token is " ")
+./arith.tests: line 151: 44 / 0 : division by 0 (error token is "0 ")
./arith.tests: line 152: let: jv += $iv: syntax error: operand expected (error token is "$iv")
./arith.tests: line 153: jv += $iv : syntax error: operand expected (error token is "$iv ")
./arith.tests: line 154: let: rv = 7 + (43 * 6: missing `)' (error token is "6")
6
1
0
-./arith.tests: line 177: 4 + : syntax error: operand expected (error token is " ")
+./arith.tests: line 177: 4 + : syntax error: operand expected (error token is "+ ")
16
./arith.tests: line 182: 4 ? : 3 + 5 : expression expected (error token is ": 3 + 5 ")
-./arith.tests: line 183: 1 ? 20 : `:' expected for conditional expression (error token is " ")
-./arith.tests: line 184: 4 ? 20 : : expression expected (error token is " ")
+./arith.tests: line 183: 1 ? 20 : `:' expected for conditional expression (error token is "20 ")
+./arith.tests: line 184: 4 ? 20 : : expression expected (error token is ": ")
9
./arith.tests: line 190: 0 && B=42 : attempted assignment to non-variable (error token is "=42 ")
9
4
4
7
-./arith.tests: line 241: 7-- : syntax error: operand expected (error token is " ")
+./arith.tests: line 241: 7-- : syntax error: operand expected (error token is "- ")
./arith.tests: line 243: --x=7 : attempted assignment to non-variable (error token is "=7 ")
./arith.tests: line 244: ++x=7 : attempted assignment to non-variable (error token is "=7 ")
./arith.tests: line 246: x++=7 : attempted assignment to non-variable (error token is "=7 ")
-7
7
7
-./arith1.sub: line 2: 4-- : syntax error: operand expected (error token is " ")
-./arith1.sub: line 3: 4++ : syntax error: operand expected (error token is " ")
-./arith1.sub: line 4: 4 -- : syntax error: operand expected (error token is " ")
-./arith1.sub: line 5: 4 ++ : syntax error: operand expected (error token is " ")
+./arith1.sub: line 2: 4-- : syntax error: operand expected (error token is "- ")
+./arith1.sub: line 3: 4++ : syntax error: operand expected (error token is "+ ")
+./arith1.sub: line 4: 4 -- : syntax error: operand expected (error token is "- ")
+./arith1.sub: line 5: 4 ++ : syntax error: operand expected (error token is "+ ")
1
2
1
2
-2
1
-./arith1.sub: line 35: ((: ++ : syntax error: operand expected (error token is " ")
+./arith1.sub: line 35: ((: ++ : syntax error: operand expected (error token is "+ ")
7
7
-./arith1.sub: line 38: ((: -- : syntax error: operand expected (error token is " ")
+./arith1.sub: line 38: ((: -- : syntax error: operand expected (error token is "- ")
7
7
7
1
4
0
-./arith2.sub: line 33: ((: -- : syntax error: operand expected (error token is " ")
+./arith2.sub: line 33: ((: -- : syntax error: operand expected (error token is "- ")
-7
-7
-./arith2.sub: line 37: ((: ++ : syntax error: operand expected (error token is " ")
+./arith2.sub: line 37: ((: ++ : syntax error: operand expected (error token is "+ ")
7
7
-7
static int brand __P((void));
static void sbrand __P((unsigned long)); /* set bash random number generator. */
+static void seedrand __P((void)); /* seed generator randomly */
static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *get_random __P((SHELL_VAR *));
#endif /* HISTORY */
/* Seed the random number generator. */
- sbrand (dollar_dollar_pid + shell_start_time);
+ seedrand ();
/* Handle some "special" variables that we may have inherited from a
parent shell. */
static int
brand ()
{
+#if 0
rseed = rseed * 1103515245 + 12345;
return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */
+#else
+ /* From "Random number generators: good ones are hard to find",
+ Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ October 1988, p. 1195. filtered through FreeBSD */
+ long h, l;
+
+ if (rseed == 0)
+ seedrand ();
+ h = rseed / 127773;
+ l = rseed % 127773;
+ rseed = 16807 * l - 2836 * h;
+ if (rseed < 0)
+ rseed += 0x7fffffff;
+ return ((unsigned int)(rseed & 32767)); /* was % 32768 */
+#endif
}
/* Set the random number generator seed to SEED. */
last_random_value = 0;
}
+static void
+seedrand ()
+{
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+ sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
+}
+
static SHELL_VAR *
assign_random (self, value, unused)
SHELL_VAR *self;
pid = getpid ();
if (subshell_environment && seeded_subshell != pid)
{
- sbrand (rseed + pid + NOW);
+ seedrand ();
seeded_subshell = pid;
}
static int brand __P((void));
static void sbrand __P((unsigned long)); /* set bash random number generator. */
+static void seedrand __P((void)); /* seed generator randomly */
static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *get_random __P((SHELL_VAR *));
#endif /* HISTORY */
/* Seed the random number generator. */
- sbrand (dollar_dollar_pid + shell_start_time);
+ seedrand ();
/* Handle some "special" variables that we may have inherited from a
parent shell. */
static int
brand ()
{
+#if 0
rseed = rseed * 1103515245 + 12345;
return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */
+#else
+ /* From "Random number generators: good ones are hard to find",
+ Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ October 1988, p. 1195. filtered through FreeBSD */
+ long h, l;
+
+ if (rseed == 0)
+ seedrand ();
+ h = rseed / 127773;
+ l = rseed % 127773;
+ rseed = 16807 * l - 2836 * h;
+ if (rseed < 0)
+ rseed += 0x7fffffff;
+ return ((unsigned int)(rseed & 32767)); /* was % 32768 */
+#endif
}
/* Set the random number generator seed to SEED. */
last_random_value = 0;
}
+static void
+seedrand ()
+{
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+ sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
+}
+
static SHELL_VAR *
assign_random (self, value, unused)
SHELL_VAR *self;
{
sbrand (strtoul (value, (char **)NULL, 10));
if (subshell_environment)
- seeded_subshell = 1;
+ seeded_subshell = getpid ();
return (self);
}
int
get_random_number ()
{
- int rv;
+ int rv, pid;
/* Reset for command and process substitution. */
- if (subshell_environment && seeded_subshell == 0)
+ pid = getpid ();
+ if (subshell_environment && seeded_subshell != pid)
{
- sbrand (rseed + getpid() + NOW);
- seeded_subshell = 1;
+ seedrand ();
+ seeded_subshell = pid;
}
do