* 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)
This commit is contained in:
parent
1ea1096a4e
commit
1a28786229
14
check.t
14
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]}
|
||||
|
49
edit.c
49
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());
|
||||
}
|
||||
|
@ -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)
|
||||
|
4
expr.c
4
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++;
|
||||
|
35
funcs.c
35
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);
|
||||
}
|
||||
|
45
lex.c
45
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 */
|
||||
|
23
main.c
23
main.c
@ -33,7 +33,7 @@
|
||||
#include <locale.h>
|
||||
#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)
|
||||
{
|
||||
|
6
sh.h
6
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);
|
||||
|
6
syn.c
6
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;
|
||||
|
70
var.c
70
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) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user