• overhaul handling of special variables
• use a combination of the one-at-a-time hash and an LCG for handling the $RANDOM special if !HAVE_ARC4RANDOM instead of rand(3)/srand(3) and get rid of time(3) usage to reduce import footprint • raise entropy state (mostly in the !HAVE_ARC4RANDOM case though…) • simplify handling of the $RANDOM_SPECIAL generally • tweak hash() to save a temp var for non-optimising compilers • some int → mksh_ari_t and other type fixes • general tweaking of code and comments
This commit is contained in:
parent
9f4376d2ad
commit
eafe88aa74
4
check.t
4
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.332 2009/10/15 16:36:25 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.333 2009/10/17 21:16:01 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/10/15
|
||||
@(#)MIRBSD KSH R39 2009/10/17
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
|
43
jobs.c
43
jobs.c
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.61 2009/09/26 03:39:59 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.62 2009/10/17 21:16:02 tg Exp $");
|
||||
|
||||
#if HAVE_KILLPG
|
||||
#define mksh_killpg killpg
|
||||
@ -339,15 +339,18 @@ exchild(struct op *t, int flags,
|
||||
volatile int *xerrok,
|
||||
/* used if XPCLOSE or XCCLOSE */ int close_fd)
|
||||
{
|
||||
static Proc *last_proc; /* for pipelines */
|
||||
static Proc *last_proc; /* for pipelines */
|
||||
|
||||
int i;
|
||||
sigset_t omask;
|
||||
Proc *p;
|
||||
Job *j;
|
||||
int rv = 0;
|
||||
int forksleep;
|
||||
int ischild;
|
||||
int i, rv = 0, forksleep;
|
||||
sigset_t omask;
|
||||
Proc *p;
|
||||
Job *j;
|
||||
struct {
|
||||
#if !HAVE_ARC4RANDOM
|
||||
pid_t thepid;
|
||||
#endif
|
||||
unsigned char ischild;
|
||||
} pi;
|
||||
|
||||
if (flags & XEXEC)
|
||||
/* Clear XFORK|XPCLOSE|XCCLOSE|XCOPROC|XPIPEO|XPIPEI|XXCOM|XBGND
|
||||
@ -410,15 +413,17 @@ exchild(struct op *t, int flags,
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
errorf("cannot fork - try again");
|
||||
}
|
||||
ischild = i == 0;
|
||||
if (ischild)
|
||||
p->pid = procpid = getpid();
|
||||
else
|
||||
p->pid = i;
|
||||
#if !HAVE_ARC4RANDOM
|
||||
pi.thepid =
|
||||
#endif
|
||||
p->pid = (pi.ischild = i == 0) ? (procpid = getpid()) : i;
|
||||
|
||||
#if !HAVE_ARC4RANDOM
|
||||
/* ensure next child gets a (slightly) different $RANDOM sequence */
|
||||
change_random(((unsigned long)p->pid << 1) | (ischild ? 1 : 0));
|
||||
/*
|
||||
* ensure next child gets a (slightly) different $RANDOM sequence
|
||||
* from its parent process and other child processes
|
||||
*/
|
||||
change_random(&pi, sizeof(pi));
|
||||
#endif
|
||||
|
||||
#ifndef MKSH_UNEMPLOYED
|
||||
@ -440,10 +445,10 @@ exchild(struct op *t, int flags,
|
||||
#endif
|
||||
|
||||
/* used to close pipe input fd */
|
||||
if (close_fd >= 0 && (((flags & XPCLOSE) && !ischild) ||
|
||||
((flags & XCCLOSE) && ischild)))
|
||||
if (close_fd >= 0 && (((flags & XPCLOSE) && !pi.ischild) ||
|
||||
((flags & XCCLOSE) && pi.ischild)))
|
||||
close(close_fd);
|
||||
if (ischild) { /* child */
|
||||
if (pi.ischild) { /* child */
|
||||
/* Do this before restoring signal */
|
||||
if (flags & XCOPROC)
|
||||
coproc_cleanup(false);
|
||||
|
27
main.c
27
main.c
@ -33,7 +33,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.152 2009/10/02 18:08:34 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.153 2009/10/17 21:16:02 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@ -93,7 +93,6 @@ main(int argc, const char *argv[])
|
||||
struct block *l;
|
||||
unsigned char restricted, errexit;
|
||||
const char **wp;
|
||||
pid_t ppid;
|
||||
struct tbl *vp;
|
||||
struct stat s_stdin;
|
||||
#if !defined(_PATH_DEFPATH) && defined(_CS_PATH)
|
||||
@ -104,11 +103,10 @@ main(int argc, const char *argv[])
|
||||
kshpid = procpid = getpid();
|
||||
ksheuid = geteuid();
|
||||
kshpgrp = getpgrp();
|
||||
ppid = getppid();
|
||||
kshppid = getppid();
|
||||
|
||||
#if !HAVE_ARC4RANDOM
|
||||
change_random((unsigned long)time(NULL));
|
||||
change_random(((unsigned long)ksheuid << 16) | kshpid);
|
||||
change_random(&kshstate_, sizeof(kshstate_));
|
||||
#endif
|
||||
|
||||
/* make sure argv[] is sane */
|
||||
@ -267,15 +265,6 @@ main(int argc, const char *argv[])
|
||||
setint(global("COLUMNS"), 0);
|
||||
setint(global("LINES"), 0);
|
||||
setint(global("OPTIND"), 1);
|
||||
vp = global("RANDOM");
|
||||
#if HAVE_ARC4RANDOM
|
||||
Flag(FARC4RANDOM) = 1;
|
||||
/* avoid calling setspec */
|
||||
vp->flag |= ISSET | INT_U;
|
||||
#else
|
||||
vp->flag |= INT_U;
|
||||
setint(vp, (mksh_ari_t)((unsigned long)kshname + 33 * ppid));
|
||||
#endif
|
||||
|
||||
safe_prompt = ksheuid ? "$ " : "# ";
|
||||
vp = global("PS1");
|
||||
@ -286,10 +275,15 @@ main(int argc, const char *argv[])
|
||||
setstr(vp, safe_prompt, KSH_RETURN_ERROR);
|
||||
setint((vp = global("PGRP")), (mksh_uari_t)kshpgrp);
|
||||
vp->flag |= INT_U;
|
||||
setint((vp = global("PPID")), (mksh_uari_t)ppid);
|
||||
setint((vp = global("PPID")), (mksh_uari_t)kshppid);
|
||||
vp->flag |= INT_U;
|
||||
setint((vp = global("RANDOM")), (mksh_uari_t)hash(kshname));
|
||||
vp->flag |= INT_U;
|
||||
setint((vp = global("USER_ID")), (mksh_uari_t)ksheuid);
|
||||
vp->flag |= INT_U;
|
||||
#if HAVE_ARC4RANDOM
|
||||
Flag(FARC4RANDOM) = 1; /* initialised */
|
||||
#endif
|
||||
|
||||
/* Set this before parsing arguments */
|
||||
#if HAVE_SETRESUGID
|
||||
@ -1261,11 +1255,10 @@ static struct tbl *ktscan(struct table *, const char *, uint32_t,
|
||||
|
||||
/* Bob Jenkins' one-at-a-time hash */
|
||||
uint32_t
|
||||
hash(const char *cp)
|
||||
oaathash_full(register const uint8_t *bp)
|
||||
{
|
||||
register uint32_t h = 0;
|
||||
register uint8_t c;
|
||||
register const uint8_t *bp = (const uint8_t *)cp;
|
||||
|
||||
while ((c = *bp++)) {
|
||||
h += c;
|
||||
|
8
mksh.1
8
mksh.1
@ -1,4 +1,4 @@
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.194 2009/10/10 21:17:30 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.195 2009/10/17 21:16:03 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: October 10 2009 $
|
||||
.Dd $Mdocdate: October 17 2009 $
|
||||
.Dt MKSH 1
|
||||
.Os MirBSD
|
||||
.Sh NAME
|
||||
@ -1810,7 +1810,7 @@ is referenced, it is assigned a 15-bit pseudo-random number, i.e. between
|
||||
0 and 32767, first, which is taken from
|
||||
.Xr arc4random 3
|
||||
if available,
|
||||
.Xr rand 3
|
||||
a Linear Congruential PRNG
|
||||
otherwise.
|
||||
.It Ev REPLY
|
||||
Default parameter for the
|
||||
@ -5736,10 +5736,8 @@ Privileged shell profile.
|
||||
.Xr arc4random 3 ,
|
||||
.Xr getopt 3 ,
|
||||
.Xr nl_langinfo 3 ,
|
||||
.Xr rand 3 ,
|
||||
.Xr setlocale 3 ,
|
||||
.Xr signal 3 ,
|
||||
.Xr srand 3 ,
|
||||
.Xr system 3 ,
|
||||
.Xr tty 4 ,
|
||||
.Xr shells 5 ,
|
||||
|
39
sh.h
39
sh.h
@ -134,9 +134,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.355 2009/10/15 16:36:27 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.356 2009/10/17 21:16:04 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R39 2009/10/15"
|
||||
#define MKSH_VERSION "R39 2009/10/17"
|
||||
|
||||
#ifndef MKSH_INCLUDES_ONLY
|
||||
|
||||
@ -348,13 +348,25 @@ typedef uint32_t mksh_uari_t;
|
||||
#define PATH_MAX 1024 /* pathname size */
|
||||
#endif
|
||||
|
||||
EXTERN const char *kshname; /* $0 */
|
||||
EXTERN pid_t kshpid; /* $$, shell pid */
|
||||
EXTERN pid_t procpid; /* pid of executing process */
|
||||
EXTERN pid_t kshpgrp; /* process group of shell */
|
||||
EXTERN uid_t ksheuid; /* effective uid of shell */
|
||||
EXTERN int exstat; /* exit status */
|
||||
EXTERN int subst_exstat; /* exit status of last $(..)/`..` */
|
||||
EXTERN struct {
|
||||
const char *kshname_; /* $0 */
|
||||
pid_t kshpid_; /* $$, shell PID */
|
||||
pid_t procpid_; /* PID of executing process */
|
||||
pid_t kshpgrp_; /* process group of shell */
|
||||
uid_t ksheuid_; /* effective UID of shell */
|
||||
pid_t kshppid_; /* PID of parent of shell */
|
||||
int exstat_; /* exit status */
|
||||
int subst_exstat_; /* exit status of last $(..)/`..` */
|
||||
} kshstate_;
|
||||
#define kshname kshstate_.kshname_
|
||||
#define kshpid kshstate_.kshpid_
|
||||
#define procpid kshstate_.procpid_
|
||||
#define kshpgrp kshstate_.kshpgrp_
|
||||
#define ksheuid kshstate_.ksheuid_
|
||||
#define kshppid kshstate_.kshppid_
|
||||
#define exstat kshstate_.exstat_
|
||||
#define subst_exstat kshstate_.subst_exstat_
|
||||
|
||||
EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */
|
||||
EXTERN const char initvsn[] I__("KSH_VERSION=@(#)MIRBSD KSH " MKSH_VERSION);
|
||||
#define KSH_VERSION (initvsn + /* "KSH_VERSION=@(#)" */ 16)
|
||||
@ -735,8 +747,8 @@ EXTERN size_t current_wd_size;
|
||||
*/
|
||||
#define MIN_COLS (2 + MIN_EDIT_SPACE + 3)
|
||||
#define MIN_LINS 3
|
||||
EXTERN int x_cols I__(80); /* tty columns */
|
||||
EXTERN int x_lins I__(-1); /* tty lines */
|
||||
EXTERN mksh_ari_t x_cols I__(80); /* tty columns */
|
||||
EXTERN mksh_ari_t x_lins I__(-1); /* tty lines */
|
||||
|
||||
/* These to avoid bracket matching problems */
|
||||
#define OPAREN '('
|
||||
@ -1505,7 +1517,8 @@ void coproc_write_close(int);
|
||||
int coproc_getfd(int, const char **);
|
||||
void coproc_cleanup(int);
|
||||
struct temp *maketemp(Area *, Temp_type, struct temp **);
|
||||
uint32_t hash(const char *);
|
||||
#define hash(s) oaathash_full((const uint8_t *)(s))
|
||||
uint32_t oaathash_full(register const uint8_t *);
|
||||
uint32_t hashmem(const void *, size_t);
|
||||
void ktinit(struct table *, Area *, size_t);
|
||||
struct tbl *ktsearch(struct table *, const char *, uint32_t);
|
||||
@ -1601,7 +1614,7 @@ int is_wdvarname(const char *, int);
|
||||
int is_wdvarassign(const char *);
|
||||
char **makenv(void);
|
||||
#if !HAVE_ARC4RANDOM
|
||||
void change_random(unsigned long);
|
||||
void change_random(const void *, size_t);
|
||||
#endif
|
||||
void change_winsz(void);
|
||||
int array_ref_len(const char *);
|
||||
|
251
var.c
251
var.c
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.94 2009/09/27 10:31:06 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.95 2009/10/17 21:16:05 tg Exp $");
|
||||
|
||||
/*
|
||||
* Variables
|
||||
@ -46,11 +46,11 @@ 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
|
||||
#if !HAVE_ARC4RANDOM
|
||||
static uint32_t oaathash_update(register uint32_t, register const uint8_t *,
|
||||
register size_t);
|
||||
|
||||
static uint32_t lcg_seed = 5381;
|
||||
#endif
|
||||
|
||||
uint8_t set_refflag = 0;
|
||||
@ -972,58 +972,45 @@ makenv(void)
|
||||
return ((char **)XPclose(denv));
|
||||
}
|
||||
|
||||
#if HAVE_ARC4RANDOM
|
||||
static int
|
||||
rnd_get(void)
|
||||
#if !HAVE_ARC4RANDOM
|
||||
static uint32_t
|
||||
oaathash_update(register uint32_t h, register const uint8_t *cp,
|
||||
register size_t n)
|
||||
{
|
||||
return (arc4random() & 0x7FFF);
|
||||
}
|
||||
|
||||
static void
|
||||
rnd_set(unsigned long newval)
|
||||
{
|
||||
#if HAVE_ARC4RANDOM_PUSHB
|
||||
if (Flag(FARC4RANDOM))
|
||||
/* initialisation, environment import, etc. already done */
|
||||
arc4random_pushb(&newval, sizeof(newval));
|
||||
else
|
||||
/* during start-up phase or somesuch */
|
||||
#endif
|
||||
arc4random_addrandom((void *)&newval, sizeof(newval));
|
||||
}
|
||||
#else
|
||||
static int
|
||||
rnd_get(void)
|
||||
{
|
||||
return (rand() & 0x7FFF);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
register unsigned int h;
|
||||
|
||||
h = rand();
|
||||
while (newval) {
|
||||
h += (newval & 0xFF);
|
||||
while (n--) {
|
||||
h += *cp++;
|
||||
h += h << 10;
|
||||
h ^= h >> 6;
|
||||
newval >>= 8;
|
||||
}
|
||||
|
||||
return (h);
|
||||
}
|
||||
|
||||
void
|
||||
change_random(const void *vp, size_t n)
|
||||
{
|
||||
register uint32_t h;
|
||||
struct {
|
||||
const void *sp, *bp, *dp;
|
||||
size_t dsz;
|
||||
struct timeval tv;
|
||||
uint32_t s;
|
||||
} i;
|
||||
|
||||
i.dp = vp;
|
||||
i.dsz = n;
|
||||
i.s = lcg_seed;
|
||||
i.bp = &lcg_seed;
|
||||
i.sp = &i;
|
||||
gettimeofday(&i.tv, NULL);
|
||||
h = oaathash_update(oaathash_update(1, (void *)&i, sizeof(i)), vp, n);
|
||||
|
||||
/* oaathash_finalise */
|
||||
h += h << 3;
|
||||
h ^= h >> 11;
|
||||
h += h << 15;
|
||||
|
||||
/* pass all of it, in case RAND_MAX is large */
|
||||
srand(h);
|
||||
lcg_seed = h;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1058,82 +1045,84 @@ static int user_lineno; /* what user set $LINENO to */
|
||||
static void
|
||||
getspec(struct tbl *vp)
|
||||
{
|
||||
int i;
|
||||
register mksh_ari_t i;
|
||||
int st;
|
||||
|
||||
switch ((i = special(vp->name))) {
|
||||
switch ((st = special(vp->name))) {
|
||||
case V_SECONDS:
|
||||
vp->flag &= ~SPECIAL;
|
||||
/* On start up the value of SECONDS is used before seconds
|
||||
* has been set - don't do anything in this case
|
||||
/*
|
||||
* On start up the value of SECONDS is used before
|
||||
* it has been set - don't do anything in this case
|
||||
* (see initcoms[] in main.c).
|
||||
*/
|
||||
if (vp->flag & ISSET) {
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
setint(vp, tv.tv_sec - seconds);
|
||||
}
|
||||
vp->flag |= SPECIAL;
|
||||
i = tv.tv_sec - seconds;
|
||||
} else
|
||||
return;
|
||||
break;
|
||||
case V_RANDOM:
|
||||
vp->flag &= ~SPECIAL;
|
||||
setint(vp, rnd_get());
|
||||
vp->flag |= SPECIAL;
|
||||
#if HAVE_ARC4RANDOM
|
||||
i = arc4random() & 0x7FFF;
|
||||
#else
|
||||
/*
|
||||
* this is the same Linear Congruential PRNG as Borland
|
||||
* C/C++ allegedly uses in its built-in rand() function
|
||||
*/
|
||||
i = ((lcg_seed = 22695477 * lcg_seed + 1) >> 16) & 0x7FFF;
|
||||
#endif
|
||||
break;
|
||||
case V_HISTSIZE:
|
||||
vp->flag &= ~SPECIAL;
|
||||
setint(vp, (mksh_ari_t)histsize);
|
||||
vp->flag |= SPECIAL;
|
||||
i = histsize;
|
||||
break;
|
||||
case V_OPTIND:
|
||||
vp->flag &= ~SPECIAL;
|
||||
setint(vp, (mksh_ari_t)user_opt.uoptind);
|
||||
vp->flag |= SPECIAL;
|
||||
i = user_opt.uoptind;
|
||||
break;
|
||||
case V_LINENO:
|
||||
vp->flag &= ~SPECIAL;
|
||||
setint(vp, (mksh_ari_t)current_lineno + user_lineno);
|
||||
vp->flag |= SPECIAL;
|
||||
i = current_lineno + user_lineno;
|
||||
break;
|
||||
case V_COLUMNS:
|
||||
case V_LINES:
|
||||
/* Do NOT export COLUMNS/LINES. Many applications
|
||||
/*
|
||||
* Do NOT export COLUMNS/LINES. Many applications
|
||||
* check COLUMNS/LINES before checking ws.ws_col/row,
|
||||
* so if the app is started with C/L in the environ
|
||||
* and the window is then resized, the app won't
|
||||
* see the change cause the environ doesn't change.
|
||||
*/
|
||||
vp->flag &= ~SPECIAL;
|
||||
change_winsz();
|
||||
setint(vp, i == V_COLUMNS ? x_cols : x_lins);
|
||||
vp->flag |= SPECIAL;
|
||||
i = st == V_COLUMNS ? x_cols : x_lins;
|
||||
break;
|
||||
default:
|
||||
/* do nothing, do not touch vp at all */
|
||||
return;
|
||||
}
|
||||
vp->flag &= ~SPECIAL;
|
||||
setint(vp, i);
|
||||
vp->flag |= SPECIAL;
|
||||
}
|
||||
|
||||
static void
|
||||
setspec(struct tbl *vp)
|
||||
{
|
||||
int i;
|
||||
mksh_ari_t i;
|
||||
char *s;
|
||||
int st;
|
||||
|
||||
switch (special(vp->name)) {
|
||||
switch ((st = special(vp->name))) {
|
||||
case V_PATH:
|
||||
if (path)
|
||||
afree(path, APERM);
|
||||
s = str_val(vp);
|
||||
strdupx(path, s, APERM);
|
||||
flushcom(1); /* clear tracked aliases */
|
||||
break;
|
||||
return;
|
||||
case V_IFS:
|
||||
setctypes(s = str_val(vp), C_IFS);
|
||||
ifs0 = *s;
|
||||
break;
|
||||
case V_OPTIND:
|
||||
vp->flag &= ~SPECIAL;
|
||||
getopts_reset((int)intval(vp));
|
||||
vp->flag |= SPECIAL;
|
||||
break;
|
||||
return;
|
||||
case V_TMPDIR:
|
||||
if (tmpdir) {
|
||||
afree(tmpdir, APERM);
|
||||
@ -1151,54 +1140,84 @@ setspec(struct tbl *vp)
|
||||
strdupx(tmpdir, s, APERM);
|
||||
}
|
||||
break;
|
||||
case V_HISTSIZE:
|
||||
vp->flag &= ~SPECIAL;
|
||||
sethistsize((int)intval(vp));
|
||||
vp->flag |= SPECIAL;
|
||||
break;
|
||||
#if HAVE_PERSISTENT_HISTORY
|
||||
case V_HISTFILE:
|
||||
sethistfile(str_val(vp));
|
||||
break;
|
||||
#endif
|
||||
case V_COLUMNS:
|
||||
vp->flag &= ~SPECIAL;
|
||||
if ((i = intval(vp)) >= MIN_COLS)
|
||||
x_cols = i;
|
||||
vp->flag |= SPECIAL;
|
||||
break;
|
||||
case V_LINES:
|
||||
vp->flag &= ~SPECIAL;
|
||||
if ((i = intval(vp)) >= MIN_LINS)
|
||||
x_lins = i;
|
||||
vp->flag |= SPECIAL;
|
||||
break;
|
||||
case V_RANDOM:
|
||||
vp->flag &= ~SPECIAL;
|
||||
rnd_set(intval(vp));
|
||||
vp->flag |= SPECIAL;
|
||||
break;
|
||||
case V_SECONDS:
|
||||
vp->flag &= ~SPECIAL;
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
seconds = tv.tv_sec - intval(vp);
|
||||
}
|
||||
vp->flag |= SPECIAL;
|
||||
break;
|
||||
case V_TMOUT:
|
||||
/* AT&T ksh seems to do this (only listen if integer) */
|
||||
if (vp->flag & INTEGER)
|
||||
ksh_tmout = vp->val.i >= 0 ? vp->val.i : 0;
|
||||
break;
|
||||
|
||||
/* common sub-cases */
|
||||
case V_OPTIND:
|
||||
case V_HISTSIZE:
|
||||
case V_COLUMNS:
|
||||
case V_LINES:
|
||||
case V_RANDOM:
|
||||
case V_SECONDS:
|
||||
case V_LINENO:
|
||||
vp->flag &= ~SPECIAL;
|
||||
/* The -1 is because line numbering starts at 1. */
|
||||
user_lineno = (unsigned int)intval(vp) - current_lineno - 1;
|
||||
i = intval(vp);
|
||||
vp->flag |= SPECIAL;
|
||||
break;
|
||||
default:
|
||||
/* do nothing, do not touch vp at all */
|
||||
return;
|
||||
}
|
||||
|
||||
/* process the singular parts of the common cases */
|
||||
|
||||
switch (st) {
|
||||
case V_OPTIND:
|
||||
getopts_reset((int)i);
|
||||
break;
|
||||
case V_HISTSIZE:
|
||||
sethistsize((int)i);
|
||||
break;
|
||||
case V_COLUMNS:
|
||||
if (i >= MIN_COLS)
|
||||
x_cols = i;
|
||||
break;
|
||||
case V_LINES:
|
||||
if (i >= MIN_LINS)
|
||||
x_lins = i;
|
||||
break;
|
||||
case V_RANDOM:
|
||||
#if HAVE_ARC4RANDOM
|
||||
#if HAVE_ARC4RANDOM_PUSHB
|
||||
if (Flag(FARC4RANDOM))
|
||||
/*
|
||||
* things like initialisation, environment import,
|
||||
* etc. are already done
|
||||
*/
|
||||
arc4random_pushb(&i, sizeof(i));
|
||||
else
|
||||
/* during start-up phase or somesuch */
|
||||
#endif /* HAVE_ARC4RANDOM_PUSHB */
|
||||
arc4random_addrandom((void *)&i, sizeof(i));
|
||||
#else /* !HAVE_ARC4RANDOM */
|
||||
/*
|
||||
* mksh R40+ no longer has the traditional repeatability
|
||||
* of $RANDOM sequences, but always retains state
|
||||
*/
|
||||
change_random(&i, sizeof(i));
|
||||
#endif /* !HAVE_ARC4RANDOM */
|
||||
break;
|
||||
case V_SECONDS:
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
seconds = tv.tv_sec - i;
|
||||
}
|
||||
break;
|
||||
case V_LINENO:
|
||||
/* The -1 is because line numbering starts at 1. */
|
||||
user_lineno = (unsigned int)i - current_lineno - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user