diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-27 00:24:11 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-27 00:24:11 +0000 |
commit | 448d30ee17aaab4faa0a927c5dcba1bc990a44db (patch) | |
tree | 4ea9e11ff010892846bfe1b5ba26a35da7bb8798 | |
parent | 843cbd54d1703e54234a2496efc920f56cd3f318 (diff) | |
download | busybox-w32-448d30ee17aaab4faa0a927c5dcba1bc990a44db.tar.gz busybox-w32-448d30ee17aaab4faa0a927c5dcba1bc990a44db.tar.bz2 busybox-w32-448d30ee17aaab4faa0a927c5dcba1bc990a44db.zip |
ash: fix very weak $RANDOM generator; and move even more things
out of data/bss
text data bss dec hex filename
807935 611 6884 815430 c7146 busybox_old
808035 611 6868 815514 c719a busybox_unstripped
-rw-r--r-- | shell/ash.c | 118 |
1 files changed, 66 insertions, 52 deletions
diff --git a/shell/ash.c b/shell/ash.c index 4a3d2d48e..8c99e30ef 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -201,6 +201,14 @@ struct globals_misc { | |||
201 | /* indicates specified signal received */ | 201 | /* indicates specified signal received */ |
202 | char gotsig[NSIG - 1]; | 202 | char gotsig[NSIG - 1]; |
203 | char *trap[NSIG]; | 203 | char *trap[NSIG]; |
204 | |||
205 | /* Rarely referenced stuff */ | ||
206 | #if ENABLE_ASH_RANDOM_SUPPORT | ||
207 | int32_t random_galois_LFSR; /* Galois LFSR (fast but weak) */ | ||
208 | uint32_t random_LCG; /* LCG1 (fast but weak) */ | ||
209 | #endif | ||
210 | pid_t backgndpid; /* pid of last background process */ | ||
211 | smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */ | ||
204 | }; | 212 | }; |
205 | extern struct globals_misc *const ash_ptr_to_globals_misc; | 213 | extern struct globals_misc *const ash_ptr_to_globals_misc; |
206 | #define G_misc (*ash_ptr_to_globals_misc) | 214 | #define G_misc (*ash_ptr_to_globals_misc) |
@@ -216,12 +224,16 @@ extern struct globals_misc *const ash_ptr_to_globals_misc; | |||
216 | #define intpending (G_misc.intpending ) | 224 | #define intpending (G_misc.intpending ) |
217 | //#define exsig (G_misc.exsig ) | 225 | //#define exsig (G_misc.exsig ) |
218 | #define pendingsig (G_misc.pendingsig ) | 226 | #define pendingsig (G_misc.pendingsig ) |
219 | #define isloginsh (G_misc.isloginsh) | 227 | #define isloginsh (G_misc.isloginsh ) |
220 | #define nullstr (G_misc.nullstr ) | 228 | #define nullstr (G_misc.nullstr ) |
221 | #define optlist (G_misc.optlist ) | 229 | #define optlist (G_misc.optlist ) |
222 | #define sigmode (G_misc.sigmode ) | 230 | #define sigmode (G_misc.sigmode ) |
223 | #define gotsig (G_misc.gotsig ) | 231 | #define gotsig (G_misc.gotsig ) |
224 | #define trap (G_misc.trap ) | 232 | #define trap (G_misc.trap ) |
233 | #define random_galois_LFSR (G_misc.random_galois_LFSR) | ||
234 | #define random_LCG (G_misc.random_LCG ) | ||
235 | #define backgndpid (G_misc.backgndpid ) | ||
236 | #define job_warning (G_misc.job_warning) | ||
225 | #define INIT_G_misc() do { \ | 237 | #define INIT_G_misc() do { \ |
226 | (*(struct globals_misc**)&ash_ptr_to_globals_misc) = xzalloc(sizeof(G_misc)); \ | 238 | (*(struct globals_misc**)&ash_ptr_to_globals_misc) = xzalloc(sizeof(G_misc)); \ |
227 | barrier(); \ | 239 | barrier(); \ |
@@ -1006,12 +1018,12 @@ struct parsefile { | |||
1006 | struct strpush basestrpush; /* so pushing one is fast */ | 1018 | struct strpush basestrpush; /* so pushing one is fast */ |
1007 | }; | 1019 | }; |
1008 | 1020 | ||
1009 | static struct parsefile basepf; /* top level input file */ | 1021 | static struct parsefile basepf; /* top level input file */ |
1010 | static struct parsefile *g_parsefile = &basepf; /* current input file */ | 1022 | static struct parsefile *g_parsefile = &basepf; /* current input file */ |
1011 | static int startlinno; /* line # where last token started */ | 1023 | static int startlinno; /* line # where last token started */ |
1012 | static char *commandname; /* currently executing command */ | 1024 | static char *commandname; /* currently executing command */ |
1013 | static struct strlist *cmdenviron; /* environment for builtin command */ | 1025 | static struct strlist *cmdenviron; /* environment for builtin command */ |
1014 | static int exitstatus; /* exit status of last command */ | 1026 | static uint8_t exitstatus; /* exit status of last command */ |
1015 | 1027 | ||
1016 | 1028 | ||
1017 | /* ============ Message printing */ | 1029 | /* ============ Message printing */ |
@@ -1605,29 +1617,6 @@ nextopt(const char *optstring) | |||
1605 | } | 1617 | } |
1606 | 1618 | ||
1607 | 1619 | ||
1608 | /* ============ Math support definitions */ | ||
1609 | |||
1610 | #if ENABLE_ASH_MATH_SUPPORT_64 | ||
1611 | typedef int64_t arith_t; | ||
1612 | #define arith_t_type long long | ||
1613 | #else | ||
1614 | typedef long arith_t; | ||
1615 | #define arith_t_type long | ||
1616 | #endif | ||
1617 | |||
1618 | #if ENABLE_ASH_MATH_SUPPORT | ||
1619 | static arith_t dash_arith(const char *); | ||
1620 | static arith_t arith(const char *expr, int *perrcode); | ||
1621 | #endif | ||
1622 | |||
1623 | #if ENABLE_ASH_RANDOM_SUPPORT | ||
1624 | static unsigned long rseed; | ||
1625 | #ifndef DYNAMIC_VAR | ||
1626 | #define DYNAMIC_VAR | ||
1627 | #endif | ||
1628 | #endif | ||
1629 | |||
1630 | |||
1631 | /* ============ Shell variables */ | 1620 | /* ============ Shell variables */ |
1632 | 1621 | ||
1633 | /* | 1622 | /* |
@@ -1694,7 +1683,7 @@ struct localvar { | |||
1694 | #define VNOFUNC 0x40 /* don't call the callback function */ | 1683 | #define VNOFUNC 0x40 /* don't call the callback function */ |
1695 | #define VNOSET 0x80 /* do not set variable - just readonly test */ | 1684 | #define VNOSET 0x80 /* do not set variable - just readonly test */ |
1696 | #define VNOSAVE 0x100 /* when text is on the heap before setvareq */ | 1685 | #define VNOSAVE 0x100 /* when text is on the heap before setvareq */ |
1697 | #ifdef DYNAMIC_VAR | 1686 | #if ENABLE_ASH_RANDOM_SUPPORT |
1698 | # define VDYNAMIC 0x200 /* dynamic variable */ | 1687 | # define VDYNAMIC 0x200 /* dynamic variable */ |
1699 | #else | 1688 | #else |
1700 | # define VDYNAMIC 0 | 1689 | # define VDYNAMIC 0 |
@@ -1966,7 +1955,7 @@ lookupvar(const char *name) | |||
1966 | 1955 | ||
1967 | v = *findvar(hashvar(name), name); | 1956 | v = *findvar(hashvar(name), name); |
1968 | if (v) { | 1957 | if (v) { |
1969 | #ifdef DYNAMIC_VAR | 1958 | #if ENABLE_ASH_RANDOM_SUPPORT |
1970 | /* | 1959 | /* |
1971 | * Dynamic variables are implemented roughly the same way they are | 1960 | * Dynamic variables are implemented roughly the same way they are |
1972 | * in bash. Namely, they're "special" so long as they aren't unset. | 1961 | * in bash. Namely, they're "special" so long as they aren't unset. |
@@ -2127,7 +2116,7 @@ unsetvar(const char *s) | |||
2127 | retval = 1; | 2116 | retval = 1; |
2128 | if (flags & VREADONLY) | 2117 | if (flags & VREADONLY) |
2129 | goto out; | 2118 | goto out; |
2130 | #ifdef DYNAMIC_VAR | 2119 | #if ENABLE_ASH_RANDOM_SUPPORT |
2131 | vp->flags &= ~VDYNAMIC; | 2120 | vp->flags &= ~VDYNAMIC; |
2132 | #endif | 2121 | #endif |
2133 | if (flags & VUNSET) | 2122 | if (flags & VUNSET) |
@@ -3243,9 +3232,6 @@ struct job { | |||
3243 | struct job *prev_job; /* previous job */ | 3232 | struct job *prev_job; /* previous job */ |
3244 | }; | 3233 | }; |
3245 | 3234 | ||
3246 | static pid_t backgndpid; /* pid of last background process */ | ||
3247 | static smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */ | ||
3248 | |||
3249 | static struct job *makejob(/*union node *,*/ int); | 3235 | static struct job *makejob(/*union node *,*/ int); |
3250 | #if !JOBS | 3236 | #if !JOBS |
3251 | #define forkshell(job, node, mode) forkshell(job, mode) | 3237 | #define forkshell(job, node, mode) forkshell(job, mode) |
@@ -3257,7 +3243,7 @@ static int waitforjob(struct job *); | |||
3257 | enum { doing_jobctl = 0 }; | 3243 | enum { doing_jobctl = 0 }; |
3258 | #define setjobctl(on) do {} while (0) | 3244 | #define setjobctl(on) do {} while (0) |
3259 | #else | 3245 | #else |
3260 | static smallint doing_jobctl; | 3246 | static smallint doing_jobctl; //references:8 |
3261 | static void setjobctl(int); | 3247 | static void setjobctl(int); |
3262 | #endif | 3248 | #endif |
3263 | 3249 | ||
@@ -3356,17 +3342,17 @@ setsignal(int signo) | |||
3356 | 3342 | ||
3357 | #if JOBS | 3343 | #if JOBS |
3358 | /* pgrp of shell on invocation */ | 3344 | /* pgrp of shell on invocation */ |
3359 | static int initialpgrp; | 3345 | static int initialpgrp; //references:2 |
3360 | static int ttyfd = -1; | 3346 | static int ttyfd = -1; //5 |
3361 | #endif | 3347 | #endif |
3362 | /* array of jobs */ | 3348 | /* array of jobs */ |
3363 | static struct job *jobtab; | 3349 | static struct job *jobtab; //5 |
3364 | /* size of array */ | 3350 | /* size of array */ |
3365 | static unsigned njobs; | 3351 | static unsigned njobs; //4 |
3366 | /* current job */ | 3352 | /* current job */ |
3367 | static struct job *curjob; | 3353 | static struct job *curjob; //lots |
3368 | /* number of presumed living untracked jobs */ | 3354 | /* number of presumed living untracked jobs */ |
3369 | static int jobless; | 3355 | static int jobless; //4 |
3370 | 3356 | ||
3371 | static void | 3357 | static void |
3372 | set_curjob(struct job *jp, unsigned mode) | 3358 | set_curjob(struct job *jp, unsigned mode) |
@@ -5041,6 +5027,19 @@ redirectsafe(union node *redir, int flags) | |||
5041 | * We have to deal with backquotes, shell variables, and file metacharacters. | 5027 | * We have to deal with backquotes, shell variables, and file metacharacters. |
5042 | */ | 5028 | */ |
5043 | 5029 | ||
5030 | #if ENABLE_ASH_MATH_SUPPORT_64 | ||
5031 | typedef int64_t arith_t; | ||
5032 | #define arith_t_type long long | ||
5033 | #else | ||
5034 | typedef long arith_t; | ||
5035 | #define arith_t_type long | ||
5036 | #endif | ||
5037 | |||
5038 | #if ENABLE_ASH_MATH_SUPPORT | ||
5039 | static arith_t dash_arith(const char *); | ||
5040 | static arith_t arith(const char *expr, int *perrcode); | ||
5041 | #endif | ||
5042 | |||
5044 | /* | 5043 | /* |
5045 | * expandarg flags | 5044 | * expandarg flags |
5046 | */ | 5045 | */ |
@@ -5358,7 +5357,7 @@ struct backcmd { /* result of evalbackcmd */ | |||
5358 | }; | 5357 | }; |
5359 | 5358 | ||
5360 | /* These forward decls are needed to use "eval" code for backticks handling: */ | 5359 | /* These forward decls are needed to use "eval" code for backticks handling: */ |
5361 | static smalluint back_exitstatus; /* exit status of backquoted command */ | 5360 | static uint8_t back_exitstatus; /* exit status of backquoted command */ |
5362 | #define EV_EXIT 01 /* exit after evaluating tree */ | 5361 | #define EV_EXIT 01 /* exit after evaluating tree */ |
5363 | static void evaltree(union node *, int); | 5362 | static void evaltree(union node *, int); |
5364 | 5363 | ||
@@ -9619,18 +9618,33 @@ setcmd(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) | |||
9619 | static void | 9618 | static void |
9620 | change_random(const char *value) | 9619 | change_random(const char *value) |
9621 | { | 9620 | { |
9621 | /* Galois LFSR parameter */ | ||
9622 | /* Taps at 32 31 29 1: */ | ||
9623 | enum { MASK = 0x8000000b }; | ||
9624 | /* Another example - taps at 32 31 30 10: */ | ||
9625 | /* MASK = 0x00400007 */ | ||
9626 | |||
9622 | if (value == NULL) { | 9627 | if (value == NULL) { |
9623 | /* "get", generate */ | 9628 | /* "get", generate */ |
9624 | char buf[16]; | 9629 | uint32_t t; |
9625 | 9630 | ||
9626 | rseed = rseed * 1103515245 + 12345; | 9631 | /* LCG has period of 2^32 and alternating lowest bit */ |
9627 | sprintf(buf, "%d", (unsigned int)((rseed & 32767))); | 9632 | random_LCG = 1664525 * random_LCG + 1013904223; |
9633 | /* Galois LFSR has period of 2^32-1 = 3 * 5 * 17 * 257 * 65537 */ | ||
9634 | t = (random_galois_LFSR << 1); | ||
9635 | if (random_galois_LFSR < 0) /* if we just shifted 1 out of msb... */ | ||
9636 | t ^= MASK; | ||
9637 | random_galois_LFSR = t; | ||
9638 | /* Both are weak, xoring them gives better randomness | ||
9639 | * and ~2^64 period. & 0x7fff is probably bash compat | ||
9640 | * for $RANDOM range. */ | ||
9641 | t = (t ^ random_LCG) & 0x7fff; | ||
9628 | /* set without recursion */ | 9642 | /* set without recursion */ |
9629 | setvar(vrandom.text, buf, VNOFUNC); | 9643 | setvar(vrandom.text, utoa(t), VNOFUNC); |
9630 | vrandom.flags &= ~VNOFUNC; | 9644 | vrandom.flags &= ~VNOFUNC; |
9631 | } else { | 9645 | } else { |
9632 | /* set/reset */ | 9646 | /* set/reset */ |
9633 | rseed = strtoul(value, (char **)NULL, 10); | 9647 | random_galois_LFSR = random_LCG = strtoul(value, (char **)NULL, 10); |
9634 | } | 9648 | } |
9635 | } | 9649 | } |
9636 | #endif | 9650 | #endif |
@@ -13417,7 +13431,7 @@ int ash_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
13417 | rootpid = getpid(); | 13431 | rootpid = getpid(); |
13418 | 13432 | ||
13419 | #if ENABLE_ASH_RANDOM_SUPPORT | 13433 | #if ENABLE_ASH_RANDOM_SUPPORT |
13420 | rseed = rootpid + time(NULL); | 13434 | random_galois_LFSR = random_LCG = rootpid + time(NULL); |
13421 | #endif | 13435 | #endif |
13422 | init(); | 13436 | init(); |
13423 | setstackmark(&smark); | 13437 | setstackmark(&smark); |