[BusyBox-cvs] busybox/shell ash.c,1.92,1.93 Config.in,1.13,1.14
Erik Andersen
andersen at busybox.net
Tue Mar 16 05:14:12 UTC 2004
Update of /var/cvs/busybox/shell
In directory nail:/tmp/cvs-serv5077/shell
Modified Files:
ash.c Config.in
Log Message:
Patch from vodz to fix the dynamic vars patch, which I should not
have checked in. Vladimir writes:
Your patch have many problem.
1. You always added + time(). This cannot reset RANDOM=value for debuging
with
replay sequential.
2. Hmm. I examine bash 2.04 source. This pseudorandom generator use low bits
of
counter value. You use high bits. This make bad pseudorandom values after
have
0-value. For example, if + time() do remove, your generator always return 0
after
first generate 0.
3. Memory leak per call. Use ash-unlike unecessary bb_strdup function.
4. Unsupport show last $RANDOM value for "set" and "export" command.
5. Bloat code. Busybox-unlike patch - added unstandart feature as default
hardcode.
Last patch attached.
Erik, why you apply Paul patch with have 5-th point problem? :(
Last patch have ash change xwrite() to fresh libbb/bb_full_write interfase
(haved loop after EINTR).
--w
vodz
Index: ash.c
===================================================================
RCS file: /var/cvs/busybox/shell/ash.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -d -r1.92 -r1.93
--- a/ash.c 15 Mar 2004 08:29:11 -0000 1.92
+++ b/ash.c 16 Mar 2004 05:14:09 -0000 1.93
@@ -33,12 +33,14 @@
* rewrite arith.y to micro stack based cryptic algorithm by
* Copyright (c) 2001 Aaron Lehmann <aaronl at vitelus.com>
*
- * Modified by Vladimir Oleynik <dzo at simtreas.ru> (c) 2001-2003 to be
- * used in busybox and size optimizations,
- * support locale, rewrited arith (see notes to this)
- *
* Modified by Paul Mundt <lethal at linux-sh.org> (c) 2004 to support
* dynamic variables.
+ *
+ * Modified by Vladimir Oleynik <dzo at simtreas.ru> (c) 2001-2004 to be
+ * used in busybox and size optimizations,
+ * rewrote arith (see notes to this), added locale support,
+ * rewrote dynamic variables.
+ *
*/
@@ -1447,6 +1449,14 @@
static int dash_arith(const char *);
#endif
+#ifdef CONFIG_ASH_RANDOM_SUPPORT
+static unsigned long rseed;
+static void change_random(const char *);
+# ifndef DYNAMIC_VAR
+# define DYNAMIC_VAR
+# endif
+#endif
+
/* $NetBSD: init.h,v 1.9 2002/11/24 22:35:40 christos Exp $ */
static void reset(void);
@@ -1467,19 +1477,18 @@
#define VNOFUNC 0x40 /* don't call the callback function */
#define VNOSET 0x80 /* do not set variable - just readonly test */
#define VNOSAVE 0x100 /* when text is on the heap before setvareq */
-#define VDYNAMIC 0x200 /* dynamic variable */
-
+#ifdef DYNAMIC_VAR
+# define VDYNAMIC 0x200 /* dynamic variable */
+# else
+# define VDYNAMIC 0
+#endif
struct var {
struct var *next; /* next entry in hash list */
int flags; /* flags are defined above */
const char *text; /* name=value */
- void (*func)(const char *);
- /* function to be called when */
+ void (*func)(const char *); /* function to be called when */
/* the variable gets set/unset */
- char *(*lookup_func)(const char *);
- /* function to be called when */
- /* the variable is read (if dynamic) */
};
struct localvar {
@@ -1506,8 +1515,6 @@
static void change_lc_ctype(const char *value);
#endif
-static char *get_random(const char *);
-static void change_random(const char *);
#define VTABSIZE 39
@@ -1522,32 +1529,33 @@
static struct var varinit[] = {
#ifdef IFS_BROKEN
- { 0, VSTRFIXED|VTEXTFIXED, defifsvar, 0, 0 },
+ { 0, VSTRFIXED|VTEXTFIXED, defifsvar, 0 },
#else
- { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0", 0, 0 },
+ { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0", 0 },
#endif
#ifdef CONFIG_ASH_MAIL
- { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0", changemail, 0 },
- { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail, 0 },
+ { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0", changemail },
+ { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail },
#endif
- { 0, VSTRFIXED|VTEXTFIXED, defpathvar, changepath, 0 },
- { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0, 0 },
- { 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0, 0 },
- { 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0, 0 },
+ { 0, VSTRFIXED|VTEXTFIXED, defpathvar, changepath },
+ { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0 },
+ { 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0 },
+ { 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0 },
#ifdef CONFIG_ASH_GETOPTS
- { 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset, 0 },
+ { 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset },
+#endif
+#ifdef CONFIG_ASH_RANDOM_SUPPORT
+ {0, VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM\0", change_random },
#endif
#ifdef CONFIG_LOCALE_SUPPORT
- {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL=", change_lc_all, 0},
- {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE=", change_lc_ctype, 0},
+ {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all },
+ {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype },
#endif
#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
- {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE=", NULL, 0},
+ {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL },
#endif
- {0, VSTRFIXED | VTEXTFIXED | VUNSET | VDYNAMIC, "RANDOM\0",
- change_random, get_random},
};
#define vifs varinit[0]
@@ -1562,7 +1570,11 @@
#define vps2 (&vps1)[1]
#define vps4 (&vps2)[1]
#define voptind (&vps4)[1]
-
+#ifdef CONFIG_ASH_GETOPTS
+#define vrandom (&voptind)[1]
+#else
+#define vrandom (&vps4)[1]
+#endif
#define defpath (defpathvar + 5)
/*
@@ -1630,12 +1642,11 @@
static void outstr(const char *, FILE *);
static void outcslow(int, FILE *);
static void flushall(void);
-static void flushout(FILE *);
+static void flusherr(void);
static int out1fmt(const char *, ...)
__attribute__((__format__(__printf__,1,2)));
static int fmtstr(char *, size_t, const char *, ...)
__attribute__((__format__(__printf__,3,4)));
-static void xwrite(int, const void *, size_t);
static int preverrout_fd; /* save fd2 before print debug if xflag is set. */
@@ -1648,7 +1659,7 @@
static void out2str(const char *p)
{
outstr(p, stderr);
- flushout(stderr);
+ flusherr();
}
/*
@@ -3287,7 +3298,7 @@
}
sp = arglist.list;
}
- xwrite(preverrout_fd, "\n", 1);
+ bb_full_write(preverrout_fd, "\n", 1);
}
cmd_is_exec = 0;
@@ -3304,7 +3315,7 @@
find_command(argv[0], &cmdentry, cmd_flag, path);
if (cmdentry.cmdtype == CMDUNKNOWN) {
status = 127;
- flushout(stderr);
+ flusherr();
goto bail;
}
@@ -4571,7 +4582,7 @@
{
herefd = fd;
expandarg(arg, (struct arglist *)NULL, 0);
- xwrite(fd, stackblock(), expdest - (char *)stackblock());
+ bb_full_write(fd, stackblock(), expdest - (char *)stackblock());
}
@@ -7905,6 +7916,10 @@
trputs("Shell args: "); trargs(argv);
#endif
rootpid = getpid();
+
+#ifdef CONFIG_ASH_RANDOM_SUPPORT
+ rseed = rootpid + ((time_t)time((time_t *)0));
+#endif
rootshell = 1;
init();
setstackmark(&smark);
@@ -8365,7 +8380,7 @@
{
size_t len = stackblocksize();
if (herefd >= 0 && len >= 1024) {
- xwrite(herefd, stackblock(), len);
+ bb_full_write(herefd, stackblock(), len);
return stackblock();
}
growstackblock();
@@ -9030,21 +9045,26 @@
#endif
+#ifdef CONFIG_ASH_RANDOM_SUPPORT
/* Roughly copied from bash.. */
-static unsigned long rseed = 1;
-static char *get_random(const char *var)
-{
- char buf[255];
- rseed = (rseed + getpid() + ((time_t)time((time_t *)0)));
- rseed = rseed * 1103515245 + 12345;
- sprintf(buf, "%d", (unsigned int)((rseed >> 16 & 32767)));
- return bb_xstrdup(buf);
-}
-
static void change_random(const char *value)
{
- rseed = strtoul(value, (char **)NULL, 10);
+ if(value == NULL) {
+ /* "get", generate */
+ char buf[16];
+
+ rseed = rseed * 1103515245 + 12345;
+ sprintf(buf, "%d", (unsigned int)((rseed & 32767)));
+ /* set without recursion */
+ setvar(vrandom.text, buf, VNOFUNC);
+ vrandom.flags &= ~VNOFUNC;
+ } else {
+ /* set/reset */
+ rseed = strtoul(value, (char **)NULL, 10);
+ }
}
+#endif
+
#ifdef CONFIG_ASH_GETOPTS
static int
@@ -9234,10 +9254,10 @@
}
void
-flushout(FILE *dest)
+flusherr(void)
{
INTOFF;
- fflush(dest);
+ fflush(stderr);
INTON;
}
@@ -9281,20 +9301,6 @@
}
-/*
- * Version of write which resumes after a signal is caught.
- */
-
-static void
-xwrite(int fd, const void *p, size_t n)
-{
- ssize_t i;
-
- do {
- i = bb_full_write(fd, p, n);
- } while (i < 0 && errno == EINTR);
-}
-
/* $NetBSD: parser.c,v 1.54 2002/11/24 22:35:42 christos Exp $ */
@@ -10951,7 +10957,7 @@
if (redir->type == NHERE) {
len = strlen(redir->nhere.doc->narg.text);
if (len <= PIPESIZE) {
- xwrite(pip[1], redir->nhere.doc->narg.text, len);
+ bb_full_write(pip[1], redir->nhere.doc->narg.text, len);
goto out;
}
}
@@ -10965,7 +10971,7 @@
#endif
signal(SIGPIPE, SIG_DFL);
if (redir->type == NHERE)
- xwrite(pip[1], redir->nhere.doc->narg.text, len);
+ bb_full_write(pip[1], redir->nhere.doc->narg.text, len);
else
expandhere(redir->nhere.doc, pip[1]);
_exit(0);
@@ -11998,10 +12004,13 @@
flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
vp = *findvar(vpp, s);
if (vp) {
- if (vp->flags & VREADONLY) {
+ if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
+ const char *n;
+
if (flags & VNOSAVE)
free(s);
- error("%.*s: is read only", strchrnul(s, '=') - s, s);
+ n = vp->text;
+ error("%.*s: is read only", strchrnul(n, '=') - n, n);
}
if (flags & VNOSET)
@@ -12058,19 +12067,20 @@
{
struct var *v;
- if ((v = *findvar(hashvar(name), name)) && !(v->flags & (VUNSET|VDYNAMIC))) {
- return strchrnul(v->text, '=') + 1;
- }
-
+ if ((v = *findvar(hashvar(name), name))) {
+#ifdef DYNAMIC_VAR
/*
* Dynamic variables are implemented roughly the same way they are
* in bash. Namely, they're "special" so long as they aren't unset.
* As soon as they're unset, they're no longer dynamic, and dynamic
* lookup will no longer happen at that point. -- PFM.
*/
- if (v && ((v->flags & VDYNAMIC)))
- if (v->lookup_func)
- return v->lookup_func(name);
+ if((v->flags & VDYNAMIC))
+ (*v->func)(NULL);
+#endif
+ if(!(v->flags & VUNSET))
+ return strchrnul(v->text, '=') + 1;
+ }
return NULL;
}
@@ -12346,8 +12356,9 @@
retval = 1;
if (flags & VREADONLY)
goto out;
- if (flags & VDYNAMIC)
- vp->flags &= ~VDYNAMIC;
+#ifdef DYNAMIC_VAR
+ vp->flags &= ~VDYNAMIC;
+#endif
if (flags & VUNSET)
goto ok;
if ((flags & VSTRFIXED) == 0) {
Index: Config.in
===================================================================
RCS file: /var/cvs/busybox/shell/Config.in,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- a/Config.in 15 Mar 2004 08:29:11 -0000 1.13
+++ b/Config.in 16 Mar 2004 05:14:10 -0000 1.14
@@ -97,6 +97,17 @@
help
Compile ash for reduced size at price of speed.
+config CONFIG_ASH_RANDOM_SUPPORT
+ bool " Enable pseudorandom generator and variable $RANDOM"
+ default n
+ depends on CONFIG_ASH
+ help
+ Enable pseudorandom generator and dynamic variable "$RANDOM".
+ Each read of "$RANDOM" will generate a new pseudorandom value.
+ You can reset the generator by using a specified start value.
+ After "unset RANDOM" then generator will switch off and this
+ variable will no longer have special treatment.
+
config CONFIG_HUSH
bool "hush"
default n
More information about the busybox-cvs
mailing list