From 1a2878622997bb4c72324060fb17af7ee7f34b53 Mon Sep 17 00:00:00 2001 From: tg Date: Wed, 23 Sep 2009 18:04:58 +0000 Subject: [PATCH] * shrink MKSH_SMALL even further by removing functionality like some GNU bash extensions (suggested by cnuke@) and bind macros * make the random cache more efficient (and the code potentially smaller, although we have a new implementation of the oaat hash function, alongside the old one, now) and pushb only if needed (i.e. state has changed or user has set $RANDOM, but not onfork) --- check.t | 14 ++++++++--- edit.c | 49 +++++++++++++++++++++++++++++--------- emacsfn.h | 4 +++- expr.c | 4 +++- funcs.c | 35 ++++++++++++++++++++++++---- lex.c | 45 +++++++++++++++++++++++++++++++---- main.c | 23 +++++++++++++++++- sh.h | 6 ++--- syn.c | 6 ++++- var.c | 70 +++++++++++++++++++++++++++++++------------------------ 10 files changed, 194 insertions(+), 62 deletions(-) diff --git a/check.t b/check.t index 67204f6..3f40fa6 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.308 2009/09/20 17:23:49 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.309 2009/09/23 18:04:53 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -25,7 +25,7 @@ # http://www.research.att.com/~gsf/public/ifs.sh expected-stdout: - @(#)MIRBSD KSH R39 2009/09/20 + @(#)MIRBSD KSH R39 2009/09/23 description: Check version of shell. stdin: @@ -4969,6 +4969,7 @@ expected-stdout: name: arrays-2 description: Check if bash-style arrays work as expected +category: !smksh stdin: v="c d" foo=(a \$v "$v" '$v' b) @@ -4993,6 +4994,7 @@ expected-stdout: name: arrays-4 description: Check if Korn Shell arrays with specified indices work as expected +category: !smksh stdin: v="c d" set -A foo -- [1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b @@ -5003,6 +5005,7 @@ expected-stdout: name: arrays-5 description: Check if bash-style arrays with specified indices work as expected +category: !smksh stdin: v="c d" foo=([1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b) @@ -5709,6 +5712,7 @@ expected-stdout: name: integer-base-one-4 description: Check if ksh93-style base-one integers work +category: !smksh stdin: set -U print 1 $(('a')) @@ -6151,6 +6155,7 @@ expected-stdout: name: event-subst-1a description: Check that '!' substitution in interactive mode works +category: !smksh file-setup: file 755 "falsetto" #! /bin/sh echo molto bene @@ -6178,6 +6183,7 @@ description: even when a space separates it from the search command, which is not what GNU bash provides but required for the other regression tests below to check +category: !smksh file-setup: file 755 "falsetto" #! /bin/sh echo molto bene @@ -6203,6 +6209,7 @@ name: event-subst-2 description: Check that '!' substitution in interactive mode does not break things +category: !smksh file-setup: file 755 "falsetto" #! /bin/sh echo molto bene @@ -6238,6 +6245,7 @@ expected-stderr-pattern: name: event-subst-3 description: Check that '!' substitution in noninteractive mode is ignored +category: !smksh file-setup: file 755 "falsetto" #! /bin/sh echo molto bene @@ -6358,7 +6366,7 @@ stdin: print ir2: $ir2 set|grep ^ir2|sed 's/^/s1: /' typeset|grep ' ir2'|sed -e 's/^/s2: /' -e 's/nameref/typeset -n/' - blub=(e1 e2 e3) + set -A blub -- e1 e2 e3 typeset -n ind=blub typeset -n ir2=blub[2] print !ind[1]: ${!ind[1]} diff --git a/edit.c b/edit.c index 82c9520..9f9d829 100644 --- a/edit.c +++ b/edit.c @@ -25,7 +25,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.180 2009/09/20 17:23:50 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.181 2009/09/23 18:04:54 tg Exp $"); /* tty driver characters we are interested in */ typedef struct { @@ -1033,13 +1033,17 @@ static int x_nextcmd; /* for newline-and-next */ static char *xmp; /* mark pointer */ static unsigned char x_last_command; static unsigned char (*x_tab)[X_TABSZ]; /* key definition */ +#ifndef MKSH_SMALL static char *(*x_atab)[X_TABSZ]; /* macro definitions */ +#endif static unsigned char x_bound[(X_TABSZ * X_NTABS + 7) / 8]; #define KILLSIZE 20 static char *killstack[KILLSIZE]; static int killsp, killtp; static int x_curprefix; +#ifndef MKSH_SMALL static char *macroptr = NULL; /* bind key macro active? */ +#endif #ifndef MKSH_NOVI static int cur_col; /* current column on line */ static int pwidth; /* width of prompt */ @@ -1069,6 +1073,9 @@ static void x_load_hist(char **); static int x_search(char *, int, int); #ifndef MKSH_SMALL static int x_search_dir(int); +int x_bind(const char *, const char *, bool, bool); +#else +int x_bind(const char *, const char *, bool); #endif static int x_match(char *, char *); static void x_redraw(int); @@ -1314,11 +1321,11 @@ x_emacs(char *buf, size_t len) if ((i = x_e_getc()) != '~') x_e_ungetc(i); } -#endif /* avoid bind key macro recursion */ if (macroptr && f == XFUNC_ins_string) f = XFUNC_insert; +#endif if (!(x_ftab[f].xf_flags & XF_PREFIX) && x_last_command != XFUNC_set_arg) { @@ -1402,6 +1409,7 @@ x_insert(int c) return (KSTD); } +#ifndef MKSH_SMALL static int x_ins_string(int c) { @@ -1412,6 +1420,7 @@ x_ins_string(int c) */ return (KSTD); } +#endif static int x_do_ins(const char *cp, size_t len) @@ -2503,22 +2512,27 @@ x_print(int prefix, int key) shprintf("%s = ", x_mapout(key)); #else shprintf("%s%s = ", x_mapout(key), (f & 0x80) ? "~" : ""); -#endif if (XFUNC_VALUE(f) != XFUNC_ins_string) +#endif shprintf("%s\n", x_ftab[XFUNC_VALUE(f)].xf_name); +#ifndef MKSH_SMALL else shprintf("'%s'\n", x_atab[prefix][key]); +#endif } int x_bind(const char *a1, const char *a2, +#ifndef MKSH_SMALL bool macro, /* bind -m */ +#endif bool list) /* bind -l */ { unsigned char f; int prefix, key; - char *sp = NULL, *m1, *m2; + char *m1, *m2; #ifndef MKSH_SMALL + char *sp = NULL; bool hastilde; #endif @@ -2538,8 +2552,11 @@ x_bind(const char *a1, const char *a2, for (prefix = 0; prefix < X_NTABS; prefix++) for (key = 0; key < X_TABSZ; key++) { f = XFUNC_VALUE(x_tab[prefix][key]); - if (f == XFUNC_insert || f == XFUNC_error || - (macro && f != XFUNC_ins_string)) + if (f == XFUNC_insert || f == XFUNC_error +#ifndef MKSH_SMALL + || (macro && f != XFUNC_ins_string) +#endif + ) continue; x_print(prefix, key); } @@ -2579,9 +2596,14 @@ x_bind(const char *a1, const char *a2, x_print(prefix, key); return (0); } - if (*a2 == 0) + if (*a2 == 0) { f = XFUNC_insert; - else if (!macro) { +#ifndef MKSH_SMALL + } else if (macro) { + f = XFUNC_ins_string; + sp = x_mapin(a2, AEDIT); +#endif + } else { for (f = 0; f < NELEM(x_ftab); f++) if (x_ftab[f].xf_name && strcmp(x_ftab[f].xf_name, a2) == 0) @@ -2590,20 +2612,21 @@ x_bind(const char *a1, const char *a2, bi_errorf("%s: no such function", a2); return (1); } - } else { - f = XFUNC_ins_string; - sp = x_mapin(a2, AEDIT); } +#ifndef MKSH_SMALL if (XFUNC_VALUE(x_tab[prefix][key]) == XFUNC_ins_string && x_atab[prefix][key]) afree(x_atab[prefix][key], AEDIT); +#endif x_tab[prefix][key] = f #ifndef MKSH_SMALL | (hastilde ? 0x80 : 0) #endif ; +#ifndef MKSH_SMALL x_atab[prefix][key] = sp; +#endif /* Track what the user has bound so x_mode(true) won't toast things */ if (f == XFUNC_insert) @@ -2634,10 +2657,12 @@ x_init_emacs(void) x_tab[x_defbindings[i].xdb_tab][x_defbindings[i].xdb_char] = x_defbindings[i].xdb_func; +#ifndef MKSH_SMALL x_atab = alloc(X_NTABS * sizeof(*x_atab), AEDIT); for (i = 1; i < X_NTABS; i++) for (j = 0; j < X_TABSZ; j++) x_atab[i][j] = NULL; +#endif } static void @@ -2876,11 +2901,13 @@ x_e_getc(void) return (c); } +#ifndef MKSH_SMALL if (macroptr) { if ((c = (unsigned char)*macroptr++)) return (c); macroptr = NULL; } +#endif return (x_getc()); } diff --git a/emacsfn.h b/emacsfn.h index e678688..789262f 100644 --- a/emacsfn.h +++ b/emacsfn.h @@ -1,5 +1,5 @@ #if defined(EMACSFN_DEFNS) -__RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.3 2009/09/20 17:23:51 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.4 2009/09/23 18:04:55 tg Exp $"); #define FN(cname,sname,flags) static int x_##cname(int); #elif defined(EMACSFN_ENUMS) #define FN(cname,sname,flags) XFUNC_##cname, @@ -41,7 +41,9 @@ FN(fold_lower, downcase-word, XF_ARG) FN(fold_upper, upcase-word, XF_ARG) #endif FN(goto_hist, goto-history, XF_ARG) +#ifndef MKSH_SMALL FN(ins_string, macro-string, XF_NOBIND) +#endif FN(insert, auto-insert, XF_ARG) FN(kill, kill-to-eol, XF_ARG) FN(kill_region, kill-region, 0) diff --git a/expr.c b/expr.c index 4147961..17da216 100644 --- a/expr.c +++ b/expr.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.34 2009/09/06 17:55:54 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.35 2009/09/23 18:04:55 tg Exp $"); /* The order of these enums is constrained by the order of opinfo[] */ enum token { @@ -528,6 +528,7 @@ exprtoken(Expr_state *es) cp += utf_ptradj(cp); strndupx(tvar, es->tokp, cp - es->tokp, ATEMP); goto process_tvar; +#ifndef MKSH_SMALL } else if (c == '\'') { ++cp; cp += utf_ptradj(cp); @@ -542,6 +543,7 @@ exprtoken(Expr_state *es) memcpy(tvar + 2, es->tokp + 1, c - 2); tvar[c] = '\0'; goto process_tvar; +#endif } else if (ksh_isdigit(c)) { while (c != '_' && (ksh_isalnux(c) || c == '#')) c = *cp++; diff --git a/funcs.c b/funcs.c index e6cc37e..e5f20d8 100644 --- a/funcs.c +++ b/funcs.c @@ -25,7 +25,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.133 2009/09/19 21:54:44 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.134 2009/09/23 18:04:56 tg Exp $"); #if HAVE_KILLPG /* @@ -1652,29 +1652,50 @@ c_getopts(const char **wp) return (optc < 0 ? 1 : rv); } +#ifndef MKSH_SMALL +extern int x_bind(const char *, const char *, bool, bool); +#else +extern int x_bind(const char *, const char *, bool); +#endif + int c_bind(const char **wp) { int optc, rv = 0; - bool macro = false, list = false; +#ifndef MKSH_SMALL + bool macro = false; +#endif + bool list = false; const char *cp; char *up; - while ((optc = ksh_getopt(wp, &builtin_opt, "lm")) != -1) + while ((optc = ksh_getopt(wp, &builtin_opt, +#ifndef MKSH_SMALL + "lm" +#else + "l" +#endif + )) != -1) switch (optc) { case 'l': list = true; break; +#ifndef MKSH_SMALL case 'm': macro = true; break; +#endif case '?': return (1); } wp += builtin_opt.optind; if (*wp == NULL) /* list all */ - rv = x_bind(NULL, NULL, 0, list); + rv = x_bind(NULL, NULL, +#ifndef MKSH_SMALL + false, +#endif + list); for (; *wp != NULL; wp++) { if ((cp = cstrchr(*wp, '=')) == NULL) @@ -1683,7 +1704,11 @@ c_bind(const char **wp) strdupx(up, *wp, ATEMP); up[cp++ - *wp] = '\0'; } - if (x_bind(up ? up : *wp, cp, macro, 0)) + if (x_bind(up ? up : *wp, cp, +#ifndef MKSH_SMALL + macro, +#endif + false)) rv = 1; afree(up, ATEMP); } diff --git a/lex.c b/lex.c index bf46218..0627305 100644 --- a/lex.c +++ b/lex.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.95 2009/09/19 22:33:10 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.96 2009/09/23 18:04:56 tg Exp $"); /* * states while lexing word @@ -77,11 +77,13 @@ struct lex_state { #define ls_sbquote ls_info.u_sbquote } u_sbquote; +#ifndef MKSH_SMALL /* =(...) */ struct sletarray_info { int nparen; /* count open parentheses */ #define ls_sletarray ls_info.u_sletarray } u_sletarray; +#endif /* ADELIM */ struct sadelim_info { @@ -129,13 +131,34 @@ static int backslash_skip; static int ignore_backslash_newline; /* optimised getsc_bn() */ -#define getsc() (*source->str != '\0' && *source->str != '\\' \ +#define _getsc() (*source->str != '\0' && *source->str != '\\' \ && !backslash_skip && !(source->flags & SF_FIRST) \ ? *source->str++ : getsc_bn()) /* optimised getsc__() */ -#define getsc_() ((*source->str != '\0') && !(source->flags & SF_FIRST) \ +#define _getsc_() ((*source->str != '\0') && !(source->flags & SF_FIRST) \ ? *source->str++ : getsc__()) +#ifdef MKSH_SMALL +static int getsc(void); +static int getsc_(void); + +static int +getsc(void) +{ + return (_getsc()); +} + +static int +getsc_(void) +{ + return (_getsc_()); +} +#else +/* !MKSH_SMALL: use them inline */ +#define getsc() _getsc() +#define getsc_() _getsc_() +#endif + #define STATE_BSIZE 32 #define PUSH_STATE(s) do { \ @@ -186,9 +209,11 @@ yylex(int cf) *wp++ = OQUOTE; /* enclose arguments in (double) quotes */ state = SLETPAREN; statep->ls_sletparen.nparen = 0; +#ifndef MKSH_SMALL } else if (cf&LETARRAY) { state = SLETARRAY; statep->ls_sletarray.nparen = 0; +#endif } else { /* normal lexing */ state = (cf & HEREDELIM) ? SHEREDELIM : SBASE; while ((c = getsc()) == ' ' || c == '\t') @@ -711,6 +736,7 @@ yylex(int cf) ++statep->ls_sletparen.nparen; goto Sbase2; +#ifndef MKSH_SMALL case SLETARRAY: /* LETARRAY: =( ... ) */ if (c == '('/*)*/) ++statep->ls_sletarray.nparen; @@ -721,6 +747,7 @@ yylex(int cf) } *wp++ = CHAR, *wp++ = c; break; +#endif case SHERESTRING: /* <<< delimiter */ if (c == '\\') { @@ -842,8 +869,10 @@ yylex(int cf) /* XXX figure out what is missing */ yyerror("no closing quote\n"); +#ifndef MKSH_SMALL if (state == SLETARRAY && statep->ls_sletarray.nparen != -1) yyerror("%s: ')' missing\n", T_synerr); +#endif /* This done to avoid tests for SHEREDELIM wherever SBASE tested */ if (state == SHEREDELIM || state == SHERESTRING) @@ -937,8 +966,12 @@ yylex(int cf) *wp++ = EOS; /* terminate word */ yylval.cp = Xclose(ws, wp); - if (state == SWORD || state == SLETPAREN || - state == SLETARRAY) /* ONEWORD? */ + if (state == SWORD || state == SLETPAREN + /* XXX ONEWORD? */ +#ifndef MKSH_SMALL + || state == SLETARRAY +#endif + ) return (LWORD); /* unget terminator */ @@ -1344,6 +1377,7 @@ getsc_line(Source *s) alarm(0); } cp = Xstring(s->xs, xp); +#ifndef MKSH_SMALL if (interactive && *cp == '!' && cur_prompt == PS1) { int linelen; @@ -1361,6 +1395,7 @@ getsc_line(Source *s) /* prepend it with "fc -e -" */ memcpy(cp, fc_e_, fc_e_n); } +#endif s->start = s->str = cp; strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp)); /* Note: if input is all nulls, this is not eof */ diff --git a/main.c b/main.c index 1f4acd7..761ca6e 100644 --- a/main.c +++ b/main.c @@ -33,7 +33,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.145 2009/09/20 16:40:55 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.146 2009/09/23 18:04:57 tg Exp $"); extern char **environ; @@ -1263,6 +1263,27 @@ hash(const char *cp) return (h); } +#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL) +uint32_t +hashmem(const void *cp, size_t len) +{ + register uint32_t h = 0; + register const uint8_t *bp = (const uint8_t *)cp; + + while (len--) { + h += *bp++; + h += h << 10; + h ^= h >> 6; + } + + h += h << 3; + h ^= h >> 11; + h += h << 15; + + return (h); +} +#endif + static void texpand(struct table *tp, size_t nsize) { diff --git a/sh.h b/sh.h index 766dc4b..1887d76 100644 --- a/sh.h +++ b/sh.h @@ -134,9 +134,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.346 2009/09/20 17:23:52 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.347 2009/09/23 18:04:57 tg Exp $"); #endif -#define MKSH_VERSION "R39 2009/09/20" +#define MKSH_VERSION "R39 2009/09/23" #ifndef MKSH_INCLUDES_ONLY @@ -1329,7 +1329,6 @@ void afree(void *, Area *); /* can take NULL */ /* edit.c */ void x_init(void); int x_read(char *, size_t); -int x_bind(const char *, const char *, bool, bool); /* UTF-8 stuff */ size_t utf_mbtowc(unsigned int *, const char *); size_t utf_wctomb(char *, unsigned int); @@ -1514,6 +1513,7 @@ int coproc_getfd(int, const char **); void coproc_cleanup(int); struct temp *maketemp(Area *, Temp_type, struct temp **); uint32_t hash(const char *); +uint32_t hashmem(const void *, size_t); void ktinit(struct table *, Area *, size_t); struct tbl *ktsearch(struct table *, const char *, uint32_t); struct tbl *ktenter(struct table *, const char *, uint32_t); diff --git a/syn.c b/syn.c index 85ccdc1..bd26e02 100644 --- a/syn.c +++ b/syn.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.42 2009/09/19 18:36:59 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.43 2009/09/23 18:04:58 tg Exp $"); struct nesting_state { int start_token; /* token than began nesting (eg, FOR) */ @@ -289,9 +289,11 @@ get_command(int cf) ACCEPT; goto Subshell; } +#ifndef MKSH_SMALL if ((XPsize(args) == 0 || Flag(FKEYWORD)) && XPsize(vars) == 1 && is_wdvarassign(yylval.cp)) goto is_wdarrassign; +#endif /* Must be a function */ if (iopn != 0 || XPsize(args) != 1 || XPsize(vars) != 0) @@ -301,6 +303,7 @@ get_command(int cf) musthave(')', 0); t = function_body(XPptrv(args)[0], false); goto Leave; +#ifndef MKSH_SMALL is_wdarrassign: { static const char set_cmd0[] = { @@ -336,6 +339,7 @@ get_command(int cf) XPput(args, yylval.cp); break; } +#endif default: goto Leave; diff --git a/var.c b/var.c index d872741..5c112a7 100644 --- a/var.c +++ b/var.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.89 2009/09/20 13:29:18 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.90 2009/09/23 18:04:58 tg Exp $"); /* * Variables @@ -973,13 +973,18 @@ makenv(void) #if HAVE_ARC4RANDOM && !defined(MKSH_SMALL) static uint32_t rnd_cache[2]; static unsigned char rnd_lastflag = 2; +#if HAVE_ARC4RANDOM_PUSHB +static bool rnd_wpush = false; +#define rnd_mix(v,w) rnd_cmix(v,w) +#else +#define rnd_mix(v,w) rnd_cmix(v) +#endif -static void rnd_cachemix(unsigned long); +static void rnd_mix(unsigned long, bool); static void -rnd_cachemix(unsigned long newval) +rnd_mix(unsigned long newval, bool wantpush) { - size_t i; struct { union { int rval; @@ -988,31 +993,26 @@ rnd_cachemix(unsigned long newval) uint32_t v1; uint32_t v2; unsigned long v3; +#if HAVE_ARC4RANDOM_PUSHB + bool neededpush; + bool wantingpush; +#endif } v; - unsigned char buf[sizeof(v) * 2 + 1], *cp, num; + +#if HAVE_ARC4RANDOM_PUSHB + v.neededpush = rnd_wpush; + v.wantingpush = wantpush; + rnd_wpush = v.neededpush || v.wantingpush; +#endif v.v0.rval = rand(); v.v1 = rnd_cache[0]; v.v2 = rnd_cache[1]; v.v3 = newval; - num = 0; - loop: - cp = (void *)&v; - i = 0; - while (i < 2 * sizeof(v)) { - buf[i++] = digits_uc[*cp >> 4]; - buf[i++] = digits_lc[*cp & 0x0F]; - ++cp; - } - buf[i] = 0; - - rnd_cache[num] = hash(buf); - if (num == 0) { - ++num; - v.v0.arval = arc4random(); - goto loop; - } + rnd_cache[0] = hashmem(&v, sizeof(v)); + v.v0.arval = arc4random(); + rnd_cache[1] = hashmem(&v, sizeof(v)); } #endif @@ -1032,17 +1032,21 @@ rnd_get(void) srand(arc4random() & 0x7FFF); else if (rnd_lastflag == 0) /* transition from 0: addrandom */ - rnd_cachemix(rand()); + rnd_mix(rand(), true); rnd_lastflag = Flag(FARC4RANDOM); } if (Flag(FARC4RANDOM)) { - if (rnd_cache[0] || rnd_cache[1]) + if (rnd_cache[0] || rnd_cache[1]) { #if HAVE_ARC4RANDOM_PUSHB - rv = arc4random_pushb(rnd_cache, sizeof(rnd_cache)); -#else + if (rnd_wpush) { + rv = arc4random_pushb(rnd_cache, + sizeof(rnd_cache)); + rnd_wpush = false; + } else +#endif arc4random_addrandom((void *)rnd_cache, sizeof(rnd_cache)); -#endif + } rnd_cache[0] = rnd_cache[1] = 0; return (( #if HAVE_ARC4RANDOM_PUSHB @@ -1066,7 +1070,7 @@ rnd_set(unsigned long newval) #endif #else #if HAVE_ARC4RANDOM - rnd_cachemix(newval); + rnd_mix(newval, true); if (Flag(FARC4RANDOM) == 1) return; if (Flag(FARC4RANDOM) == 2) @@ -1080,9 +1084,9 @@ rnd_set(unsigned long newval) #if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL) /* - * Called after a fork in parent to bump the random number generator. + * Called after a fork to bump the random number generator. * Done to ensure children will not get the same random number sequence - * if the parent doesn't use $RANDOM. + * as the parent processes. */ void change_random(unsigned long newval) @@ -1091,7 +1095,7 @@ change_random(unsigned long newval) #if HAVE_ARC4RANDOM if (Flag(FARC4RANDOM)) { - rnd_cachemix(newval); + rnd_mix(newval, false); return; } #endif @@ -1413,7 +1417,9 @@ set_array(const char *var, bool reset, const char **vals) struct tbl *vp, *vq; mksh_uari_t i, n; const char *ccp; +#ifndef MKSH_SMALL char *cp; +#endif /* to get local array, use "typeset foo; set -A foo" */ vp = global(var); @@ -1430,6 +1436,7 @@ set_array(const char *var, bool reset, const char **vals) * evaluation of some of vals[] may fail... */ for (n = i = 0; (ccp = vals[i]); n = ++i) { +#ifndef MKSH_SMALL if (*ccp == '[') { int level = 0; @@ -1449,6 +1456,7 @@ set_array(const char *var, bool reset, const char **vals) } else ccp = vals[i]; } +#endif vq = arraysearch(vp, n); /* would be nice to deal with errors here... (see above) */