From a59d14b56593058e17638602d9fe0908928080bb Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 26 Sep 2009 03:40:03 +0000 Subject: [PATCH] further optimise and simplify the handling of $RANDOM, reads and writes to it are now either arc4random or rand/srand, but srand retains the old state; set +o arc4random is no longer possible, but if it's there we use arc4random(3), if not, we use rand(3) for $RANDOM reads; optimise special variable handling too and fix a few consts and other minor things --- check.t | 8 +-- funcs.c | 6 +- jobs.c | 6 +- main.c | 84 +++++++++++------------ mksh.1 | 26 +++----- sh.h | 30 +++------ sh_flags.h | 7 +- syn.c | 4 +- var.c | 190 ++++++++++++++--------------------------------------- var_spec.h | 39 +++++++++++ 10 files changed, 158 insertions(+), 242 deletions(-) create mode 100644 var_spec.h diff --git a/check.t b/check.t index 0c2e5e0..0e561f4 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.310 2009/09/24 17:15:29 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.311 2009/09/26 03:39:57 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/24 + @(#)MIRBSD KSH R39 2009/09/25 description: Check version of shell. stdin: @@ -4042,8 +4042,8 @@ description: isn't exec-ed stdin: sortprog=$(whence -p sort) || sortprog=cat - env | $sortprog >bar1 - FOO=bar exec; env | $sortprog >bar2 + env | $sortprog | grep -v '^RANDOM=' >bar1 + FOO=bar exec; env | $sortprog | grep -v '^RANDOM=' >bar2 cmp -s bar1 bar2 --- name: xxx-what-do-you-call-this-1 diff --git a/funcs.c b/funcs.c index e5f20d8..485335f 100644 --- a/funcs.c +++ b/funcs.c @@ -25,7 +25,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.134 2009/09/23 18:04:56 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.135 2009/09/26 03:39:58 tg Exp $"); #if HAVE_KILLPG /* @@ -94,7 +94,7 @@ const struct builtin mkshbuiltins[] = { #endif {"pwd", c_pwd}, {"*=readonly", c_typeset}, - {"=typeset", c_typeset}, + {T__typeset, c_typeset}, {"+unalias", c_unalias}, {"whence", c_whence}, #ifndef MKSH_UNEMPLOYED @@ -2309,7 +2309,7 @@ c_set(const char **wp) const char **owp; if (wp[1] == NULL) { - static const char *args [] = { "set", "-", NULL }; + static const char *args[] = { "set", "-", NULL }; return (c_typeset(args)); } diff --git a/jobs.c b/jobs.c index 76bce7e..b7c526a 100644 --- a/jobs.c +++ b/jobs.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.60 2009/09/20 16:40:55 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.61 2009/09/26 03:39:59 tg Exp $"); #if HAVE_KILLPG #define mksh_killpg killpg @@ -416,8 +416,8 @@ exchild(struct op *t, int flags, else p->pid = i; -#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL) - /* Ensure next child gets a (slightly) different $RANDOM sequence */ +#if !HAVE_ARC4RANDOM + /* ensure next child gets a (slightly) different $RANDOM sequence */ change_random(((unsigned long)p->pid << 1) | (ischild ? 1 : 0)); #endif diff --git a/main.c b/main.c index dc8b3ff..001a215 100644 --- a/main.c +++ b/main.c @@ -33,7 +33,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.148 2009/09/26 01:08:27 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.149 2009/09/26 03:40:00 tg Exp $"); extern char **environ; @@ -47,17 +47,17 @@ static void remove_temps(struct temp *); static const char initifs[] = "IFS= \t\n"; -static const char initsubs[] = "${PS2=> } ${PS3=#? } ${PS4=+ }"; +static const char initsubs[] = + "${PS2=> } ${PS3=#? } ${PS4=+ } ${SECONDS=0} ${TMOUT=0}"; static const char *initcoms[] = { - "typeset", "-r", initvsn, NULL, - "typeset", "-x", "SHELL", "PATH", "HOME", NULL, - "typeset", "-i10", "COLUMNS=0", "LINES=0", "OPTIND=1", NULL, - "typeset", "-Ui10", "PGRP", "PPID", "RANDOM", "USER_ID", NULL, - "eval", "typeset -i10 SECONDS=\"${SECONDS-0}\" TMOUT=\"${TMOUT-0}\"", - NULL, - "alias", "integer=typeset -i", "local=typeset", NULL, + T_typeset, "-r", initvsn, NULL, + T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL, + T_typeset, "-i10", "COLUMNS", "LINES", "OPTIND", "PGRP", "PPID", + "RANDOM", "SECONDS", "TMOUT", "USER_ID", NULL, "alias", + "integer=typeset -i", + T_local_typeset, "hash=alias -t", /* not "alias -t --": hash -r needs to work */ "type=whence -v", #ifndef MKSH_UNEMPLOYED @@ -101,8 +101,14 @@ main(int argc, const char *argv[]) char *cp; #endif + kshpid = procpid = getpid(); + ksheuid = geteuid(); + kshpgrp = getpgrp(); + ppid = getppid(); + #if !HAVE_ARC4RANDOM - change_random((unsigned long)time(NULL) * getpid()); + change_random((unsigned long)time(NULL)); + change_random(((unsigned long)ksheuid << 16) | kshpid); #endif /* make sure argv[] is sane */ @@ -204,13 +210,14 @@ main(int argc, const char *argv[]) #endif #ifdef MKSH_BINSHREDUCED - /* Set FPOSIX if we're called as -sh or /bin/sh or so */ + /* set FPOSIX if we're called as -sh or /bin/sh or so */ { const char *cc; cc = kshname; i = 0; argi = 0; while (cc[i] != '\0') + /* the following line matches '-' and '/' ;-) */ if ((cc[i++] | 2) == '/') argi = i; if (((cc[argi] | 0x20) == 's') && ((cc[argi + 1] | 0x20) == 'h')) @@ -223,7 +230,6 @@ main(int argc, const char *argv[]) for (wp = (const char **)environ; *wp != NULL; wp++) typeset(*wp, IMPORT | EXPORT, 0, 0, 0); - kshpid = procpid = getpid(); typeset(initifs, 0, 0, 0, 0); /* for security */ /* assign default shell variable values */ @@ -252,31 +258,38 @@ main(int argc, const char *argv[]) /* setstr can't fail here */ setstr(pwd_v, current_wd, KSH_RETURN_ERROR); } - ppid = getppid(); -#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL) - change_random(((unsigned long)kshname) ^ - ((unsigned long)time(NULL) * kshpid * ppid)); -#endif -#if HAVE_ARC4RANDOM - Flag(FARC4RANDOM) = 2; /* use arc4random(3) until $RANDOM is written */ -#endif for (wp = initcoms; *wp != NULL; wp++) { shcomexec(wp); while (*wp != NULL) wp++; } + setint(global("COLUMNS"), 0); + setint(global("LINES"), 0); + setint(global("OPTIND"), 1); + vp = global("RANDOM"); +#if HAVE_ARC4RANDOM + /* avoid calling setspec */ + Flag(FARC4RANDOM) = 1; + vp->flag |= ISSET | INT_U; +#else + vp->flag |= INT_U; + setint(vp, (mksh_ari_t)((unsigned long)kshname + 33 * ppid)); +#endif - safe_prompt = (ksheuid = geteuid()) ? "$ " : "# "; + safe_prompt = ksheuid ? "$ " : "# "; vp = global("PS1"); /* Set PS1 if unset or we are root and prompt doesn't contain a # */ if (!(vp->flag & ISSET) || (!ksheuid && !strchr(str_val(vp), '#'))) /* setstr can't fail here */ setstr(vp, safe_prompt, KSH_RETURN_ERROR); - setint(global("PGRP"), (mksh_uari_t)(kshpgrp = getpgrp())); - setint(global("PPID"), (mksh_uari_t)ppid); - setint(global("USER_ID"), (mksh_uari_t)ksheuid); + setint((vp = global("PGRP")), (mksh_uari_t)kshpgrp); + vp->flag |= INT_U; + setint((vp = global("PPID")), (mksh_uari_t)ppid); + vp->flag |= INT_U; + setint((vp = global("USER_ID")), (mksh_uari_t)ksheuid); + vp->flag |= INT_U; /* Set this before parsing arguments */ #if HAVE_SETRESUGID @@ -408,7 +421,7 @@ main(int argc, const char *argv[]) if (restricted) { static const char *restr_com[] = { - "typeset", "-r", "PATH", + T_typeset, "-r", "PATH", "ENV", "SHELL", NULL }; @@ -1263,27 +1276,6 @@ 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/mksh.1 b/mksh.1 index 5f0a40c..1b41e25 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.191 2009/09/20 17:23:51 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.192 2009/09/26 03:40:00 tg Exp $ .\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 @@ -48,7 +48,7 @@ .el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 .. .\"- -.Dd $Mdocdate: September 20 2009 $ +.Dd $Mdocdate: September 26 2009 $ .Dt MKSH 1 .Os MirBSD .Sh NAME @@ -1807,10 +1807,11 @@ if the shell doesn't know where it is. Every time .Ev RANDOM is referenced, it is assigned a 15-bit pseudo-random number, i.e. between -0 and 32767, first. -See the description of -.Ic set \-o Ic arc4random -below for details. +0 and 32767, first, which is taken from +.Xr arc4random 3 +if available, +.Xr rand 3 +otherwise. .It Ev REPLY Default parameter for the .Ic read @@ -3735,17 +3736,10 @@ Print commands and parameter assignments when they are executed, preceded by the value of .Ev PS4 . .It Ic arc4random -Use +If this shell option, which cannot be unset, exists, .Xr arc4random 3 -high-quality random numbers for the value of -.Ev RANDOM -if set (to either 1 or 2), or a semi-predictable sequence from -.Xr rand 3 -if unset. -Setting this flag will change its value to 1; the default value is 2, -which means it automatically switches to 0 if -.Ev RANDOM -is written to. +is used for the value of +.Ev RANDOM . .It Ic bgnice Background jobs are run with lower priority. .It Ic braceexpand diff --git a/sh.h b/sh.h index 7305375..ec4a087 100644 --- a/sh.h +++ b/sh.h @@ -134,9 +134,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.348 2009/09/24 17:15:32 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.349 2009/09/26 03:40:01 tg Exp $"); #endif -#define MKSH_VERSION "R39 2009/09/24" +#define MKSH_VERSION "R39 2009/09/25" #ifndef MKSH_INCLUDES_ONLY @@ -567,8 +567,11 @@ EXTERN char null[] I__(""); /* helpers for string pooling */ #define T_synerr "syntax error" EXTERN const char r_fc_e_[] I__("r=fc -e -"); -#define fc_e_ (r_fc_e_ + 2) /* "fc -e -" */ -#define fc_e_n 7 /* strlen(fc_e_) */ +#define fc_e_ (r_fc_e_ + 2) /* "fc -e -" */ +#define fc_e_n 7 /* strlen(fc_e_) */ +EXTERN const char T_local_typeset[] I__("local=typeset"); +#define T__typeset (T_local_typeset + 5) /* "=typeset" */ +#define T_typeset (T_local_typeset + 6) /* "typeset" */ enum temp_type { TT_HEREDOC_EXP, /* expanded heredoc */ @@ -963,21 +966,6 @@ struct builtin { extern const struct builtin mkshbuiltins[]; -/* var spec values */ -#define V_NONE 0 -#define V_COLUMNS 1 -#define V_HISTFILE 2 -#define V_HISTSIZE 3 -#define V_IFS 4 -#define V_LINENO 5 -#define V_LINES 6 -#define V_OPTIND 7 -#define V_PATH 8 -#define V_RANDOM 9 -#define V_SECONDS 10 -#define V_TMOUT 11 -#define V_TMPDIR 12 - /* values for set_prompt() */ #define PS1 0 /* command */ #define PS2 1 /* command continuation */ @@ -1601,11 +1589,9 @@ void initvar(void); struct tbl *global(const char *); struct tbl *local(const char *, bool); char *str_val(struct tbl *); -mksh_ari_t intval(struct tbl *); int setstr(struct tbl *, const char *, int); struct tbl *setint_v(struct tbl *, struct tbl *, bool); void setint(struct tbl *, mksh_ari_t); -int getint(struct tbl *, mksh_ari_t *, bool); struct tbl *typeset(const char *, Tflag, Tflag, int, int); void unset(struct tbl *, int); const char *skip_varname(const char *, int); @@ -1613,7 +1599,7 @@ const char *skip_wdvarname(const char *, int); int is_wdvarname(const char *, int); int is_wdvarassign(const char *); char **makenv(void); -#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL) +#if !HAVE_ARC4RANDOM void change_random(unsigned long); #endif void change_winsz(void); diff --git a/sh_flags.h b/sh_flags.h index 689f2e9..82e0385 100644 --- a/sh_flags.h +++ b/sh_flags.h @@ -1,5 +1,5 @@ #if defined(SHFLAGS_DEFNS) -__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.2 2009/09/24 17:15:33 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.3 2009/09/26 03:40:02 tg Exp $"); #define FN(sname,cname,ochar,flags) /* nothing */ #elif defined(SHFLAGS_ENUMS) #define FN(sname,cname,ochar,flags) cname, @@ -22,9 +22,8 @@ __RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.2 2009/09/24 17:15:33 tg Exp $"); F0("allexport", FEXPORT, 'a', OF_ANY) #if HAVE_ARC4RANDOM -/* ./. for $RANDOM (non-standard), use the following function scheme: */ -/* 0:rand(3) 1:arc4random(3) 2:switch from 1 to 0 on write */ -FN("arc4random", FARC4RANDOM, 0, OF_ANY) +/* ./. backwards compat: available if arc4random(3) is used for $RANDOM */ +FN("arc4random", FARC4RANDOM, 0, OF_INTERNAL) #endif #if HAVE_NICE diff --git a/syn.c b/syn.c index bd26e02..f3d771c 100644 --- a/syn.c +++ b/syn.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.43 2009/09/23 18:04:58 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.44 2009/09/26 03:40:02 tg Exp $"); struct nesting_state { int start_token; /* token than began nesting (eg, FOR) */ @@ -877,7 +877,7 @@ assign_command(char *s) return ((strcmp(s, "alias") == 0) || (strcmp(s, "export") == 0) || (strcmp(s, "readonly") == 0) || - (strcmp(s, "typeset") == 0)); + (strcmp(s, T_typeset) == 0)); } /* Check if we are in the middle of reading an alias */ diff --git a/var.c b/var.c index 7bb09fd..cdd737d 100644 --- a/var.c +++ b/var.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.91 2009/09/23 18:22:38 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.92 2009/09/26 03:40:02 tg Exp $"); /* * Variables @@ -42,10 +42,16 @@ static void unspecial(const char *); static void getspec(struct tbl *); static void setspec(struct tbl *); static void unsetspec(struct tbl *); +static int getint(struct tbl *, mksh_ari_t *, bool); +static mksh_ari_t intval(struct tbl *); static struct tbl *arraysearch(struct tbl *, uint32_t); static const char *array_index_calc(const char *, bool *, uint32_t *); static int rnd_get(void); +#if HAVE_ARC4RANDOM static void rnd_set(unsigned long); +#else +#define rnd_set change_random +#endif uint8_t set_refflag = 0; @@ -101,38 +107,33 @@ popblock(void) } /* called by main() to initialise variable data structures */ +#define VARSPEC_DEFNS +#include "var_spec.h" + +enum var_specs { +#define VARSPEC_ENUMS +#include "var_spec.h" + V_MAX +}; + +static const char * const initvar_names[] = { +#define VARSPEC_ITEMS +#include "var_spec.h" +}; + void initvar(void) { - static const struct { - const char *name; - int v; - } names[] = { - { "COLUMNS", V_COLUMNS }, -#if HAVE_PERSISTENT_HISTORY - { "HISTFILE", V_HISTFILE }, -#endif - { "HISTSIZE", V_HISTSIZE }, - { "IFS", V_IFS }, - { "LINENO", V_LINENO }, - { "LINES", V_LINES }, - { "OPTIND", V_OPTIND }, - { "PATH", V_PATH }, - { "RANDOM", V_RANDOM }, - { "SECONDS", V_SECONDS }, - { "TMOUT", V_TMOUT }, - { "TMPDIR", V_TMPDIR }, - { NULL, 0 } - }; - int i; + int i = 0; struct tbl *tp; ktinit(&specials, APERM, /* must be 80% of 2^n (currently 12 specials) */ 16); - for (i = 0; names[i].name; i++) { - tp = ktenter(&specials, names[i].name, hash(names[i].name)); + while (i < V_MAX - 1) { + tp = ktenter(&specials, initvar_names[i], + hash(initvar_names[i])); tp->flag = DEFINED|ISSET; - tp->type = names[i].v; + tp->type = ++i; } } @@ -384,7 +385,7 @@ str_val(struct tbl *vp) } /* get variable integer value, with error checking */ -mksh_ari_t +static mksh_ari_t intval(struct tbl *vp) { mksh_ari_t num; @@ -461,7 +462,7 @@ setint(struct tbl *vq, mksh_ari_t n) setspec(vq); } -int +static int getint(struct tbl *vp, mksh_ari_t *nump, bool arith) { char *s; @@ -964,150 +965,55 @@ makenv(void) return ((char **)XPclose(denv)); } -/* - * Get us a random number, either from rand(3) or arc4random(3), with - * the latter being preferred. If Flag(FARC4RANDOM) is 0, we use rand(3), - * otherwise arc4random(3). We have static caches to make change_random - * and writes to $RANDOM a cheap operation. - */ -#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_mix(unsigned long, bool); - -static void -rnd_mix(unsigned long newval, bool wantpush) -{ - struct { - union { - int rval; - uint32_t arval; - } v0; - uint32_t v1; - uint32_t v2; - unsigned long v3; -#if HAVE_ARC4RANDOM_PUSHB - bool neededpush; - bool wantingpush; -#endif - } v; - -#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; - - rnd_cache[0] = hashmem(&v, sizeof(v)); - v.v0.arval = arc4random(); - rnd_cache[1] = hashmem(&v, sizeof(v)); -} -#endif - +#if HAVE_ARC4RANDOM static int rnd_get(void) { -#if HAVE_ARC4RANDOM && defined(MKSH_SMALL) return (arc4random() & 0x7FFF); -#else -#if HAVE_ARC4RANDOM -#if HAVE_ARC4RANDOM_PUSHB - uint32_t rv = 0; -#endif - if (Flag(FARC4RANDOM) != rnd_lastflag) { - if (Flag(FARC4RANDOM) == 0) - /* transition to 0 by set: srand */ - srand(arc4random() & 0x7FFF); - else if (rnd_lastflag == 0) - /* transition from 0: addrandom */ - rnd_mix(rand(), true); - rnd_lastflag = Flag(FARC4RANDOM); - } - if (Flag(FARC4RANDOM)) { - if (rnd_cache[0] || rnd_cache[1]) { -#if HAVE_ARC4RANDOM_PUSHB - if (rnd_wpush) { - rv = arc4random_pushb(rnd_cache, - sizeof(rnd_cache)); - rnd_wpush = false; - } else -#endif - arc4random_addrandom((void *)rnd_cache, - sizeof(rnd_cache)); - } - rnd_cache[0] = rnd_cache[1] = 0; - return (( -#if HAVE_ARC4RANDOM_PUSHB - rv ? rv : -#endif - arc4random()) & 0x7FFF); - } -#endif - return (rand() & 0x7FFF); -#endif } static void rnd_set(unsigned long newval) { -#if HAVE_ARC4RANDOM && defined(MKSH_SMALL) #if HAVE_ARC4RANDOM_PUSHB arc4random_pushb(&newval, sizeof(newval)); #else arc4random_addrandom((void *)&newval, sizeof(newval)); #endif +} #else -#if HAVE_ARC4RANDOM - rnd_mix(newval, true); - if (Flag(FARC4RANDOM) == 1) - return; - if (Flag(FARC4RANDOM) == 2) - Flag(FARC4RANDOM) = 0; - /* transition to 0 by write: only srand */ - rnd_lastflag = 0; -#endif - srand(newval & 0x7FFF); -#endif +static int +rnd_get(void) +{ + return (rand() & 0x7FFF); } -#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL) /* * Called after a fork to bump the random number generator. * Done to ensure children will not get the same random number sequence * as the parent processes. + * Also called as rnd_set - mksh R40+ no longer has the traditional + * repeatability of randomness sequences, state is always retained. */ void change_random(unsigned long newval) { - int rval = 0; + register unsigned int h; -#if HAVE_ARC4RANDOM - if (Flag(FARC4RANDOM)) { - rnd_mix(newval, false); - return; + h = rand(); + while (newval) { + h += (newval & 0xFF); + h += h << 10; + h ^= h >> 6; + newval >>= 8; } -#endif - rval += newval & 0x7FFF; - newval >>= 15; - rval += newval & 0x7FFF; - newval >>= 15; - rval += newval + rand(); - rval = (rval & 0x7FFF) ^ (rval >> 15); + h += h << 3; + h ^= h >> 11; + h += h << 15; - srand(rval); + /* pass all of it, in case RAND_MAX is large */ + srand(h); } #endif diff --git a/var_spec.h b/var_spec.h new file mode 100644 index 0000000..4035cc9 --- /dev/null +++ b/var_spec.h @@ -0,0 +1,39 @@ +#if defined(VARSPEC_DEFNS) +__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.1 2009/09/26 03:40:03 tg Exp $"); +#define FN(name) /* nothing */ +#elif defined(VARSPEC_ENUMS) +#define FN(name) V_##name, +#define F0(name) V_##name = 0, +#elif defined(VARSPEC_ITEMS) +#define F0(name) /* nothing */ +#define FN(name) #name, +#endif + +#ifndef F0 +#define F0 FN +#endif + +/* 0 is always V_NONE */ +F0(NONE) + +/* 1 and up are special variables */ +FN(COLUMNS) +#if HAVE_PERSISTENT_HISTORY +FN(HISTFILE) +#endif +FN(HISTSIZE) +FN(IFS) +FN(LINENO) +FN(LINES) +FN(OPTIND) +FN(PATH) +FN(RANDOM) +FN(SECONDS) +FN(TMOUT) +FN(TMPDIR) + +#undef FN +#undef F0 +#undef VARSPEC_DEFNS +#undef VARSPEC_ENUMS +#undef VARSPEC_ITEMS