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
This commit is contained in:
parent
b50b43e3bf
commit
a59d14b565
8
check.t
8
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: 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: 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 $
|
# $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
|
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||||
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)MIRBSD KSH R39 2009/09/24
|
@(#)MIRBSD KSH R39 2009/09/25
|
||||||
description:
|
description:
|
||||||
Check version of shell.
|
Check version of shell.
|
||||||
stdin:
|
stdin:
|
||||||
@ -4042,8 +4042,8 @@ description:
|
|||||||
isn't exec-ed
|
isn't exec-ed
|
||||||
stdin:
|
stdin:
|
||||||
sortprog=$(whence -p sort) || sortprog=cat
|
sortprog=$(whence -p sort) || sortprog=cat
|
||||||
env | $sortprog >bar1
|
env | $sortprog | grep -v '^RANDOM=' >bar1
|
||||||
FOO=bar exec; env | $sortprog >bar2
|
FOO=bar exec; env | $sortprog | grep -v '^RANDOM=' >bar2
|
||||||
cmp -s bar1 bar2
|
cmp -s bar1 bar2
|
||||||
---
|
---
|
||||||
name: xxx-what-do-you-call-this-1
|
name: xxx-what-do-you-call-this-1
|
||||||
|
4
funcs.c
4
funcs.c
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
@ -94,7 +94,7 @@ const struct builtin mkshbuiltins[] = {
|
|||||||
#endif
|
#endif
|
||||||
{"pwd", c_pwd},
|
{"pwd", c_pwd},
|
||||||
{"*=readonly", c_typeset},
|
{"*=readonly", c_typeset},
|
||||||
{"=typeset", c_typeset},
|
{T__typeset, c_typeset},
|
||||||
{"+unalias", c_unalias},
|
{"+unalias", c_unalias},
|
||||||
{"whence", c_whence},
|
{"whence", c_whence},
|
||||||
#ifndef MKSH_UNEMPLOYED
|
#ifndef MKSH_UNEMPLOYED
|
||||||
|
6
jobs.c
6
jobs.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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
|
#if HAVE_KILLPG
|
||||||
#define mksh_killpg killpg
|
#define mksh_killpg killpg
|
||||||
@ -416,8 +416,8 @@ exchild(struct op *t, int flags,
|
|||||||
else
|
else
|
||||||
p->pid = i;
|
p->pid = i;
|
||||||
|
|
||||||
#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL)
|
#if !HAVE_ARC4RANDOM
|
||||||
/* Ensure next child gets a (slightly) different $RANDOM sequence */
|
/* ensure next child gets a (slightly) different $RANDOM sequence */
|
||||||
change_random(((unsigned long)p->pid << 1) | (ischild ? 1 : 0));
|
change_random(((unsigned long)p->pid << 1) | (ischild ? 1 : 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
84
main.c
84
main.c
@ -33,7 +33,7 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#endif
|
#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;
|
extern char **environ;
|
||||||
|
|
||||||
@ -47,17 +47,17 @@ static void remove_temps(struct temp *);
|
|||||||
|
|
||||||
static const char initifs[] = "IFS= \t\n";
|
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[] = {
|
static const char *initcoms[] = {
|
||||||
"typeset", "-r", initvsn, NULL,
|
T_typeset, "-r", initvsn, NULL,
|
||||||
"typeset", "-x", "SHELL", "PATH", "HOME", NULL,
|
T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
|
||||||
"typeset", "-i10", "COLUMNS=0", "LINES=0", "OPTIND=1", NULL,
|
T_typeset, "-i10", "COLUMNS", "LINES", "OPTIND", "PGRP", "PPID",
|
||||||
"typeset", "-Ui10", "PGRP", "PPID", "RANDOM", "USER_ID", NULL,
|
"RANDOM", "SECONDS", "TMOUT", "USER_ID", NULL,
|
||||||
"eval", "typeset -i10 SECONDS=\"${SECONDS-0}\" TMOUT=\"${TMOUT-0}\"",
|
|
||||||
NULL,
|
|
||||||
"alias", "integer=typeset -i", "local=typeset", NULL,
|
|
||||||
"alias",
|
"alias",
|
||||||
|
"integer=typeset -i",
|
||||||
|
T_local_typeset,
|
||||||
"hash=alias -t", /* not "alias -t --": hash -r needs to work */
|
"hash=alias -t", /* not "alias -t --": hash -r needs to work */
|
||||||
"type=whence -v",
|
"type=whence -v",
|
||||||
#ifndef MKSH_UNEMPLOYED
|
#ifndef MKSH_UNEMPLOYED
|
||||||
@ -101,8 +101,14 @@ main(int argc, const char *argv[])
|
|||||||
char *cp;
|
char *cp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
kshpid = procpid = getpid();
|
||||||
|
ksheuid = geteuid();
|
||||||
|
kshpgrp = getpgrp();
|
||||||
|
ppid = getppid();
|
||||||
|
|
||||||
#if !HAVE_ARC4RANDOM
|
#if !HAVE_ARC4RANDOM
|
||||||
change_random((unsigned long)time(NULL) * getpid());
|
change_random((unsigned long)time(NULL));
|
||||||
|
change_random(((unsigned long)ksheuid << 16) | kshpid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make sure argv[] is sane */
|
/* make sure argv[] is sane */
|
||||||
@ -204,13 +210,14 @@ main(int argc, const char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MKSH_BINSHREDUCED
|
#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;
|
const char *cc;
|
||||||
|
|
||||||
cc = kshname;
|
cc = kshname;
|
||||||
i = 0; argi = 0;
|
i = 0; argi = 0;
|
||||||
while (cc[i] != '\0')
|
while (cc[i] != '\0')
|
||||||
|
/* the following line matches '-' and '/' ;-) */
|
||||||
if ((cc[i++] | 2) == '/')
|
if ((cc[i++] | 2) == '/')
|
||||||
argi = i;
|
argi = i;
|
||||||
if (((cc[argi] | 0x20) == 's') && ((cc[argi + 1] | 0x20) == 'h'))
|
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++)
|
for (wp = (const char **)environ; *wp != NULL; wp++)
|
||||||
typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
|
typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
|
||||||
|
|
||||||
kshpid = procpid = getpid();
|
|
||||||
typeset(initifs, 0, 0, 0, 0); /* for security */
|
typeset(initifs, 0, 0, 0, 0); /* for security */
|
||||||
|
|
||||||
/* assign default shell variable values */
|
/* assign default shell variable values */
|
||||||
@ -252,31 +258,38 @@ main(int argc, const char *argv[])
|
|||||||
/* setstr can't fail here */
|
/* setstr can't fail here */
|
||||||
setstr(pwd_v, current_wd, KSH_RETURN_ERROR);
|
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++) {
|
for (wp = initcoms; *wp != NULL; wp++) {
|
||||||
shcomexec(wp);
|
shcomexec(wp);
|
||||||
while (*wp != NULL)
|
while (*wp != NULL)
|
||||||
wp++;
|
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");
|
vp = global("PS1");
|
||||||
/* Set PS1 if unset or we are root and prompt doesn't contain a # */
|
/* Set PS1 if unset or we are root and prompt doesn't contain a # */
|
||||||
if (!(vp->flag & ISSET) ||
|
if (!(vp->flag & ISSET) ||
|
||||||
(!ksheuid && !strchr(str_val(vp), '#')))
|
(!ksheuid && !strchr(str_val(vp), '#')))
|
||||||
/* setstr can't fail here */
|
/* setstr can't fail here */
|
||||||
setstr(vp, safe_prompt, KSH_RETURN_ERROR);
|
setstr(vp, safe_prompt, KSH_RETURN_ERROR);
|
||||||
setint(global("PGRP"), (mksh_uari_t)(kshpgrp = getpgrp()));
|
setint((vp = global("PGRP")), (mksh_uari_t)kshpgrp);
|
||||||
setint(global("PPID"), (mksh_uari_t)ppid);
|
vp->flag |= INT_U;
|
||||||
setint(global("USER_ID"), (mksh_uari_t)ksheuid);
|
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 */
|
/* Set this before parsing arguments */
|
||||||
#if HAVE_SETRESUGID
|
#if HAVE_SETRESUGID
|
||||||
@ -408,7 +421,7 @@ main(int argc, const char *argv[])
|
|||||||
|
|
||||||
if (restricted) {
|
if (restricted) {
|
||||||
static const char *restr_com[] = {
|
static const char *restr_com[] = {
|
||||||
"typeset", "-r", "PATH",
|
T_typeset, "-r", "PATH",
|
||||||
"ENV", "SHELL",
|
"ENV", "SHELL",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
@ -1263,27 +1276,6 @@ hash(const char *cp)
|
|||||||
return (h);
|
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
|
static void
|
||||||
texpand(struct table *tp, size_t nsize)
|
texpand(struct table *tp, size_t nsize)
|
||||||
{
|
{
|
||||||
|
26
mksh.1
26
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 $
|
.\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $
|
||||||
.\"-
|
.\"-
|
||||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||||
@ -48,7 +48,7 @@
|
|||||||
.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
|
.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
|
||||||
..
|
..
|
||||||
.\"-
|
.\"-
|
||||||
.Dd $Mdocdate: September 20 2009 $
|
.Dd $Mdocdate: September 26 2009 $
|
||||||
.Dt MKSH 1
|
.Dt MKSH 1
|
||||||
.Os MirBSD
|
.Os MirBSD
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -1807,10 +1807,11 @@ if the shell doesn't know where it is.
|
|||||||
Every time
|
Every time
|
||||||
.Ev RANDOM
|
.Ev RANDOM
|
||||||
is referenced, it is assigned a 15-bit pseudo-random number, i.e. between
|
is referenced, it is assigned a 15-bit pseudo-random number, i.e. between
|
||||||
0 and 32767, first.
|
0 and 32767, first, which is taken from
|
||||||
See the description of
|
.Xr arc4random 3
|
||||||
.Ic set \-o Ic arc4random
|
if available,
|
||||||
below for details.
|
.Xr rand 3
|
||||||
|
otherwise.
|
||||||
.It Ev REPLY
|
.It Ev REPLY
|
||||||
Default parameter for the
|
Default parameter for the
|
||||||
.Ic read
|
.Ic read
|
||||||
@ -3735,17 +3736,10 @@ Print commands and parameter assignments when they are executed, preceded by
|
|||||||
the value of
|
the value of
|
||||||
.Ev PS4 .
|
.Ev PS4 .
|
||||||
.It Ic arc4random
|
.It Ic arc4random
|
||||||
Use
|
If this shell option, which cannot be unset, exists,
|
||||||
.Xr arc4random 3
|
.Xr arc4random 3
|
||||||
high-quality random numbers for the value of
|
is used for the value of
|
||||||
.Ev RANDOM
|
.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.
|
|
||||||
.It Ic bgnice
|
.It Ic bgnice
|
||||||
Background jobs are run with lower priority.
|
Background jobs are run with lower priority.
|
||||||
.It Ic braceexpand
|
.It Ic braceexpand
|
||||||
|
26
sh.h
26
sh.h
@ -134,9 +134,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#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
|
#endif
|
||||||
#define MKSH_VERSION "R39 2009/09/24"
|
#define MKSH_VERSION "R39 2009/09/25"
|
||||||
|
|
||||||
#ifndef MKSH_INCLUDES_ONLY
|
#ifndef MKSH_INCLUDES_ONLY
|
||||||
|
|
||||||
@ -569,6 +569,9 @@ EXTERN char null[] I__("");
|
|||||||
EXTERN const char r_fc_e_[] I__("r=fc -e -");
|
EXTERN const char r_fc_e_[] I__("r=fc -e -");
|
||||||
#define fc_e_ (r_fc_e_ + 2) /* "fc -e -" */
|
#define fc_e_ (r_fc_e_ + 2) /* "fc -e -" */
|
||||||
#define fc_e_n 7 /* strlen(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 {
|
enum temp_type {
|
||||||
TT_HEREDOC_EXP, /* expanded heredoc */
|
TT_HEREDOC_EXP, /* expanded heredoc */
|
||||||
@ -963,21 +966,6 @@ struct builtin {
|
|||||||
|
|
||||||
extern const struct builtin mkshbuiltins[];
|
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() */
|
/* values for set_prompt() */
|
||||||
#define PS1 0 /* command */
|
#define PS1 0 /* command */
|
||||||
#define PS2 1 /* command continuation */
|
#define PS2 1 /* command continuation */
|
||||||
@ -1601,11 +1589,9 @@ void initvar(void);
|
|||||||
struct tbl *global(const char *);
|
struct tbl *global(const char *);
|
||||||
struct tbl *local(const char *, bool);
|
struct tbl *local(const char *, bool);
|
||||||
char *str_val(struct tbl *);
|
char *str_val(struct tbl *);
|
||||||
mksh_ari_t intval(struct tbl *);
|
|
||||||
int setstr(struct tbl *, const char *, int);
|
int setstr(struct tbl *, const char *, int);
|
||||||
struct tbl *setint_v(struct tbl *, struct tbl *, bool);
|
struct tbl *setint_v(struct tbl *, struct tbl *, bool);
|
||||||
void setint(struct tbl *, mksh_ari_t);
|
void setint(struct tbl *, mksh_ari_t);
|
||||||
int getint(struct tbl *, mksh_ari_t *, bool);
|
|
||||||
struct tbl *typeset(const char *, Tflag, Tflag, int, int);
|
struct tbl *typeset(const char *, Tflag, Tflag, int, int);
|
||||||
void unset(struct tbl *, int);
|
void unset(struct tbl *, int);
|
||||||
const char *skip_varname(const char *, 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_wdvarname(const char *, int);
|
||||||
int is_wdvarassign(const char *);
|
int is_wdvarassign(const char *);
|
||||||
char **makenv(void);
|
char **makenv(void);
|
||||||
#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL)
|
#if !HAVE_ARC4RANDOM
|
||||||
void change_random(unsigned long);
|
void change_random(unsigned long);
|
||||||
#endif
|
#endif
|
||||||
void change_winsz(void);
|
void change_winsz(void);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#if defined(SHFLAGS_DEFNS)
|
#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 */
|
#define FN(sname,cname,ochar,flags) /* nothing */
|
||||||
#elif defined(SHFLAGS_ENUMS)
|
#elif defined(SHFLAGS_ENUMS)
|
||||||
#define FN(sname,cname,ochar,flags) cname,
|
#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)
|
F0("allexport", FEXPORT, 'a', OF_ANY)
|
||||||
|
|
||||||
#if HAVE_ARC4RANDOM
|
#if HAVE_ARC4RANDOM
|
||||||
/* ./. for $RANDOM (non-standard), use the following function scheme: */
|
/* ./. backwards compat: available if arc4random(3) is used for $RANDOM */
|
||||||
/* 0:rand(3) 1:arc4random(3) 2:switch from 1 to 0 on write */
|
FN("arc4random", FARC4RANDOM, 0, OF_INTERNAL)
|
||||||
FN("arc4random", FARC4RANDOM, 0, OF_ANY)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_NICE
|
#if HAVE_NICE
|
||||||
|
4
syn.c
4
syn.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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 {
|
struct nesting_state {
|
||||||
int start_token; /* token than began nesting (eg, FOR) */
|
int start_token; /* token than began nesting (eg, FOR) */
|
||||||
@ -877,7 +877,7 @@ assign_command(char *s)
|
|||||||
return ((strcmp(s, "alias") == 0) ||
|
return ((strcmp(s, "alias") == 0) ||
|
||||||
(strcmp(s, "export") == 0) ||
|
(strcmp(s, "export") == 0) ||
|
||||||
(strcmp(s, "readonly") == 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 */
|
/* Check if we are in the middle of reading an alias */
|
||||||
|
190
var.c
190
var.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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
|
* Variables
|
||||||
@ -42,10 +42,16 @@ static void unspecial(const char *);
|
|||||||
static void getspec(struct tbl *);
|
static void getspec(struct tbl *);
|
||||||
static void setspec(struct tbl *);
|
static void setspec(struct tbl *);
|
||||||
static void unsetspec(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 struct tbl *arraysearch(struct tbl *, uint32_t);
|
||||||
static const char *array_index_calc(const char *, bool *, uint32_t *);
|
static const char *array_index_calc(const char *, bool *, uint32_t *);
|
||||||
static int rnd_get(void);
|
static int rnd_get(void);
|
||||||
|
#if HAVE_ARC4RANDOM
|
||||||
static void rnd_set(unsigned long);
|
static void rnd_set(unsigned long);
|
||||||
|
#else
|
||||||
|
#define rnd_set change_random
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t set_refflag = 0;
|
uint8_t set_refflag = 0;
|
||||||
|
|
||||||
@ -101,38 +107,33 @@ popblock(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* called by main() to initialise variable data structures */
|
/* 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
|
void
|
||||||
initvar(void)
|
initvar(void)
|
||||||
{
|
{
|
||||||
static const struct {
|
int i = 0;
|
||||||
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;
|
|
||||||
struct tbl *tp;
|
struct tbl *tp;
|
||||||
|
|
||||||
ktinit(&specials, APERM,
|
ktinit(&specials, APERM,
|
||||||
/* must be 80% of 2^n (currently 12 specials) */ 16);
|
/* must be 80% of 2^n (currently 12 specials) */ 16);
|
||||||
for (i = 0; names[i].name; i++) {
|
while (i < V_MAX - 1) {
|
||||||
tp = ktenter(&specials, names[i].name, hash(names[i].name));
|
tp = ktenter(&specials, initvar_names[i],
|
||||||
|
hash(initvar_names[i]));
|
||||||
tp->flag = DEFINED|ISSET;
|
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 */
|
/* get variable integer value, with error checking */
|
||||||
mksh_ari_t
|
static mksh_ari_t
|
||||||
intval(struct tbl *vp)
|
intval(struct tbl *vp)
|
||||||
{
|
{
|
||||||
mksh_ari_t num;
|
mksh_ari_t num;
|
||||||
@ -461,7 +462,7 @@ setint(struct tbl *vq, mksh_ari_t n)
|
|||||||
setspec(vq);
|
setspec(vq);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
getint(struct tbl *vp, mksh_ari_t *nump, bool arith)
|
getint(struct tbl *vp, mksh_ari_t *nump, bool arith)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
@ -964,150 +965,55 @@ makenv(void)
|
|||||||
return ((char **)XPclose(denv));
|
return ((char **)XPclose(denv));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#if HAVE_ARC4RANDOM
|
||||||
* 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
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rnd_get(void)
|
rnd_get(void)
|
||||||
{
|
{
|
||||||
#if HAVE_ARC4RANDOM && defined(MKSH_SMALL)
|
|
||||||
return (arc4random() & 0x7FFF);
|
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
|
static void
|
||||||
rnd_set(unsigned long newval)
|
rnd_set(unsigned long newval)
|
||||||
{
|
{
|
||||||
#if HAVE_ARC4RANDOM && defined(MKSH_SMALL)
|
|
||||||
#if HAVE_ARC4RANDOM_PUSHB
|
#if HAVE_ARC4RANDOM_PUSHB
|
||||||
arc4random_pushb(&newval, sizeof(newval));
|
arc4random_pushb(&newval, sizeof(newval));
|
||||||
#else
|
#else
|
||||||
arc4random_addrandom((void *)&newval, sizeof(newval));
|
arc4random_addrandom((void *)&newval, sizeof(newval));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#if HAVE_ARC4RANDOM
|
static int
|
||||||
rnd_mix(newval, true);
|
rnd_get(void)
|
||||||
if (Flag(FARC4RANDOM) == 1)
|
{
|
||||||
return;
|
return (rand() & 0x7FFF);
|
||||||
if (Flag(FARC4RANDOM) == 2)
|
|
||||||
Flag(FARC4RANDOM) = 0;
|
|
||||||
/* transition to 0 by write: only srand */
|
|
||||||
rnd_lastflag = 0;
|
|
||||||
#endif
|
|
||||||
srand(newval & 0x7FFF);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL)
|
|
||||||
/*
|
/*
|
||||||
* Called after a fork 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
|
* Done to ensure children will not get the same random number sequence
|
||||||
* as the parent processes.
|
* 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
|
void
|
||||||
change_random(unsigned long newval)
|
change_random(unsigned long newval)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
register unsigned int h;
|
||||||
|
|
||||||
#if HAVE_ARC4RANDOM
|
h = rand();
|
||||||
if (Flag(FARC4RANDOM)) {
|
while (newval) {
|
||||||
rnd_mix(newval, false);
|
h += (newval & 0xFF);
|
||||||
return;
|
h += h << 10;
|
||||||
|
h ^= h >> 6;
|
||||||
|
newval >>= 8;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
rval += newval & 0x7FFF;
|
h += h << 3;
|
||||||
newval >>= 15;
|
h ^= h >> 11;
|
||||||
rval += newval & 0x7FFF;
|
h += h << 15;
|
||||||
newval >>= 15;
|
|
||||||
rval += newval + rand();
|
|
||||||
rval = (rval & 0x7FFF) ^ (rval >> 15);
|
|
||||||
|
|
||||||
srand(rval);
|
/* pass all of it, in case RAND_MAX is large */
|
||||||
|
srand(h);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
39
var_spec.h
Normal file
39
var_spec.h
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user