diff options
author | Eric Andersen <andersen@codepoet.org> | 2004-03-16 05:14:10 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2004-03-16 05:14:10 +0000 |
commit | 16767e2377210fb7489ee4d7d79ad1850c7c932d (patch) | |
tree | 60d41b5ef57193173d1eecd747a0ddb3130e90ea | |
parent | ca65ca7d450ae6cbc0702e6b10925ccaef982bb4 (diff) | |
download | busybox-w32-16767e2377210fb7489ee4d7d79ad1850c7c932d.tar.gz busybox-w32-16767e2377210fb7489ee4d7d79ad1850c7c932d.tar.bz2 busybox-w32-16767e2377210fb7489ee4d7d79ad1850c7c932d.zip |
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
-rw-r--r-- | shell/Config.in | 11 | ||||
-rw-r--r-- | shell/ash.c | 161 |
2 files changed, 97 insertions, 75 deletions
diff --git a/shell/Config.in b/shell/Config.in index bcb5e719b..34baaa45c 100644 --- a/shell/Config.in +++ b/shell/Config.in | |||
@@ -97,6 +97,17 @@ config CONFIG_ASH_OPTIMIZE_FOR_SIZE | |||
97 | help | 97 | help |
98 | Compile ash for reduced size at price of speed. | 98 | Compile ash for reduced size at price of speed. |
99 | 99 | ||
100 | config CONFIG_ASH_RANDOM_SUPPORT | ||
101 | bool " Enable pseudorandom generator and variable $RANDOM" | ||
102 | default n | ||
103 | depends on CONFIG_ASH | ||
104 | help | ||
105 | Enable pseudorandom generator and dynamic variable "$RANDOM". | ||
106 | Each read of "$RANDOM" will generate a new pseudorandom value. | ||
107 | You can reset the generator by using a specified start value. | ||
108 | After "unset RANDOM" then generator will switch off and this | ||
109 | variable will no longer have special treatment. | ||
110 | |||
100 | config CONFIG_HUSH | 111 | config CONFIG_HUSH |
101 | bool "hush" | 112 | bool "hush" |
102 | default n | 113 | default n |
diff --git a/shell/ash.c b/shell/ash.c index 060860c07..5072528f4 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -33,12 +33,14 @@ | |||
33 | * rewrite arith.y to micro stack based cryptic algorithm by | 33 | * rewrite arith.y to micro stack based cryptic algorithm by |
34 | * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com> | 34 | * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com> |
35 | * | 35 | * |
36 | * Modified by Vladimir Oleynik <dzo@simtreas.ru> (c) 2001-2003 to be | ||
37 | * used in busybox and size optimizations, | ||
38 | * support locale, rewrited arith (see notes to this) | ||
39 | * | ||
40 | * Modified by Paul Mundt <lethal@linux-sh.org> (c) 2004 to support | 36 | * Modified by Paul Mundt <lethal@linux-sh.org> (c) 2004 to support |
41 | * dynamic variables. | 37 | * dynamic variables. |
38 | * | ||
39 | * Modified by Vladimir Oleynik <dzo@simtreas.ru> (c) 2001-2004 to be | ||
40 | * used in busybox and size optimizations, | ||
41 | * rewrote arith (see notes to this), added locale support, | ||
42 | * rewrote dynamic variables. | ||
43 | * | ||
42 | */ | 44 | */ |
43 | 45 | ||
44 | 46 | ||
@@ -1447,6 +1449,14 @@ static void unsetfunc(const char *); | |||
1447 | static int dash_arith(const char *); | 1449 | static int dash_arith(const char *); |
1448 | #endif | 1450 | #endif |
1449 | 1451 | ||
1452 | #ifdef CONFIG_ASH_RANDOM_SUPPORT | ||
1453 | static unsigned long rseed; | ||
1454 | static void change_random(const char *); | ||
1455 | # ifndef DYNAMIC_VAR | ||
1456 | # define DYNAMIC_VAR | ||
1457 | # endif | ||
1458 | #endif | ||
1459 | |||
1450 | /* $NetBSD: init.h,v 1.9 2002/11/24 22:35:40 christos Exp $ */ | 1460 | /* $NetBSD: init.h,v 1.9 2002/11/24 22:35:40 christos Exp $ */ |
1451 | 1461 | ||
1452 | static void reset(void); | 1462 | static void reset(void); |
@@ -1467,19 +1477,18 @@ static void reset(void); | |||
1467 | #define VNOFUNC 0x40 /* don't call the callback function */ | 1477 | #define VNOFUNC 0x40 /* don't call the callback function */ |
1468 | #define VNOSET 0x80 /* do not set variable - just readonly test */ | 1478 | #define VNOSET 0x80 /* do not set variable - just readonly test */ |
1469 | #define VNOSAVE 0x100 /* when text is on the heap before setvareq */ | 1479 | #define VNOSAVE 0x100 /* when text is on the heap before setvareq */ |
1470 | #define VDYNAMIC 0x200 /* dynamic variable */ | 1480 | #ifdef DYNAMIC_VAR |
1471 | 1481 | # define VDYNAMIC 0x200 /* dynamic variable */ | |
1482 | # else | ||
1483 | # define VDYNAMIC 0 | ||
1484 | #endif | ||
1472 | 1485 | ||
1473 | struct var { | 1486 | struct var { |
1474 | struct var *next; /* next entry in hash list */ | 1487 | struct var *next; /* next entry in hash list */ |
1475 | int flags; /* flags are defined above */ | 1488 | int flags; /* flags are defined above */ |
1476 | const char *text; /* name=value */ | 1489 | const char *text; /* name=value */ |
1477 | void (*func)(const char *); | 1490 | void (*func)(const char *); /* function to be called when */ |
1478 | /* function to be called when */ | ||
1479 | /* the variable gets set/unset */ | 1491 | /* the variable gets set/unset */ |
1480 | char *(*lookup_func)(const char *); | ||
1481 | /* function to be called when */ | ||
1482 | /* the variable is read (if dynamic) */ | ||
1483 | }; | 1492 | }; |
1484 | 1493 | ||
1485 | struct localvar { | 1494 | struct localvar { |
@@ -1506,8 +1515,6 @@ static void change_lc_all(const char *value); | |||
1506 | static void change_lc_ctype(const char *value); | 1515 | static void change_lc_ctype(const char *value); |
1507 | #endif | 1516 | #endif |
1508 | 1517 | ||
1509 | static char *get_random(const char *); | ||
1510 | static void change_random(const char *); | ||
1511 | 1518 | ||
1512 | #define VTABSIZE 39 | 1519 | #define VTABSIZE 39 |
1513 | 1520 | ||
@@ -1522,32 +1529,33 @@ static const char defifs[] = " \t\n"; | |||
1522 | 1529 | ||
1523 | static struct var varinit[] = { | 1530 | static struct var varinit[] = { |
1524 | #ifdef IFS_BROKEN | 1531 | #ifdef IFS_BROKEN |
1525 | { 0, VSTRFIXED|VTEXTFIXED, defifsvar, 0, 0 }, | 1532 | { 0, VSTRFIXED|VTEXTFIXED, defifsvar, 0 }, |
1526 | #else | 1533 | #else |
1527 | { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0", 0, 0 }, | 1534 | { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0", 0 }, |
1528 | #endif | 1535 | #endif |
1529 | 1536 | ||
1530 | #ifdef CONFIG_ASH_MAIL | 1537 | #ifdef CONFIG_ASH_MAIL |
1531 | { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0", changemail, 0 }, | 1538 | { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0", changemail }, |
1532 | { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail, 0 }, | 1539 | { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail }, |
1533 | #endif | 1540 | #endif |
1534 | 1541 | ||
1535 | { 0, VSTRFIXED|VTEXTFIXED, defpathvar, changepath, 0 }, | 1542 | { 0, VSTRFIXED|VTEXTFIXED, defpathvar, changepath }, |
1536 | { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0, 0 }, | 1543 | { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0 }, |
1537 | { 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0, 0 }, | 1544 | { 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0 }, |
1538 | { 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0, 0 }, | 1545 | { 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0 }, |
1539 | #ifdef CONFIG_ASH_GETOPTS | 1546 | #ifdef CONFIG_ASH_GETOPTS |
1540 | { 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset, 0 }, | 1547 | { 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset }, |
1548 | #endif | ||
1549 | #ifdef CONFIG_ASH_RANDOM_SUPPORT | ||
1550 | {0, VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM\0", change_random }, | ||
1541 | #endif | 1551 | #endif |
1542 | #ifdef CONFIG_LOCALE_SUPPORT | 1552 | #ifdef CONFIG_LOCALE_SUPPORT |
1543 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL=", change_lc_all, 0}, | 1553 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all }, |
1544 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE=", change_lc_ctype, 0}, | 1554 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype }, |
1545 | #endif | 1555 | #endif |
1546 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | 1556 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY |
1547 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE=", NULL, 0}, | 1557 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL }, |
1548 | #endif | 1558 | #endif |
1549 | {0, VSTRFIXED | VTEXTFIXED | VUNSET | VDYNAMIC, "RANDOM\0", | ||
1550 | change_random, get_random}, | ||
1551 | }; | 1559 | }; |
1552 | 1560 | ||
1553 | #define vifs varinit[0] | 1561 | #define vifs varinit[0] |
@@ -1562,7 +1570,11 @@ static struct var varinit[] = { | |||
1562 | #define vps2 (&vps1)[1] | 1570 | #define vps2 (&vps1)[1] |
1563 | #define vps4 (&vps2)[1] | 1571 | #define vps4 (&vps2)[1] |
1564 | #define voptind (&vps4)[1] | 1572 | #define voptind (&vps4)[1] |
1565 | 1573 | #ifdef CONFIG_ASH_GETOPTS | |
1574 | #define vrandom (&voptind)[1] | ||
1575 | #else | ||
1576 | #define vrandom (&vps4)[1] | ||
1577 | #endif | ||
1566 | #define defpath (defpathvar + 5) | 1578 | #define defpath (defpathvar + 5) |
1567 | 1579 | ||
1568 | /* | 1580 | /* |
@@ -1630,12 +1642,11 @@ extern char **environ; | |||
1630 | static void outstr(const char *, FILE *); | 1642 | static void outstr(const char *, FILE *); |
1631 | static void outcslow(int, FILE *); | 1643 | static void outcslow(int, FILE *); |
1632 | static void flushall(void); | 1644 | static void flushall(void); |
1633 | static void flushout(FILE *); | 1645 | static void flusherr(void); |
1634 | static int out1fmt(const char *, ...) | 1646 | static int out1fmt(const char *, ...) |
1635 | __attribute__((__format__(__printf__,1,2))); | 1647 | __attribute__((__format__(__printf__,1,2))); |
1636 | static int fmtstr(char *, size_t, const char *, ...) | 1648 | static int fmtstr(char *, size_t, const char *, ...) |
1637 | __attribute__((__format__(__printf__,3,4))); | 1649 | __attribute__((__format__(__printf__,3,4))); |
1638 | static void xwrite(int, const void *, size_t); | ||
1639 | 1650 | ||
1640 | static int preverrout_fd; /* save fd2 before print debug if xflag is set. */ | 1651 | static int preverrout_fd; /* save fd2 before print debug if xflag is set. */ |
1641 | 1652 | ||
@@ -1648,7 +1659,7 @@ static void out1str(const char *p) | |||
1648 | static void out2str(const char *p) | 1659 | static void out2str(const char *p) |
1649 | { | 1660 | { |
1650 | outstr(p, stderr); | 1661 | outstr(p, stderr); |
1651 | flushout(stderr); | 1662 | flusherr(); |
1652 | } | 1663 | } |
1653 | 1664 | ||
1654 | /* | 1665 | /* |
@@ -3287,7 +3298,7 @@ evalcommand(union node *cmd, int flags) | |||
3287 | } | 3298 | } |
3288 | sp = arglist.list; | 3299 | sp = arglist.list; |
3289 | } | 3300 | } |
3290 | xwrite(preverrout_fd, "\n", 1); | 3301 | bb_full_write(preverrout_fd, "\n", 1); |
3291 | } | 3302 | } |
3292 | 3303 | ||
3293 | cmd_is_exec = 0; | 3304 | cmd_is_exec = 0; |
@@ -3304,7 +3315,7 @@ evalcommand(union node *cmd, int flags) | |||
3304 | find_command(argv[0], &cmdentry, cmd_flag, path); | 3315 | find_command(argv[0], &cmdentry, cmd_flag, path); |
3305 | if (cmdentry.cmdtype == CMDUNKNOWN) { | 3316 | if (cmdentry.cmdtype == CMDUNKNOWN) { |
3306 | status = 127; | 3317 | status = 127; |
3307 | flushout(stderr); | 3318 | flusherr(); |
3308 | goto bail; | 3319 | goto bail; |
3309 | } | 3320 | } |
3310 | 3321 | ||
@@ -4571,7 +4582,7 @@ expandhere(union node *arg, int fd) | |||
4571 | { | 4582 | { |
4572 | herefd = fd; | 4583 | herefd = fd; |
4573 | expandarg(arg, (struct arglist *)NULL, 0); | 4584 | expandarg(arg, (struct arglist *)NULL, 0); |
4574 | xwrite(fd, stackblock(), expdest - (char *)stackblock()); | 4585 | bb_full_write(fd, stackblock(), expdest - (char *)stackblock()); |
4575 | } | 4586 | } |
4576 | 4587 | ||
4577 | 4588 | ||
@@ -7905,6 +7916,10 @@ ash_main(int argc, char **argv) | |||
7905 | trputs("Shell args: "); trargs(argv); | 7916 | trputs("Shell args: "); trargs(argv); |
7906 | #endif | 7917 | #endif |
7907 | rootpid = getpid(); | 7918 | rootpid = getpid(); |
7919 | |||
7920 | #ifdef CONFIG_ASH_RANDOM_SUPPORT | ||
7921 | rseed = rootpid + ((time_t)time((time_t *)0)); | ||
7922 | #endif | ||
7908 | rootshell = 1; | 7923 | rootshell = 1; |
7909 | init(); | 7924 | init(); |
7910 | setstackmark(&smark); | 7925 | setstackmark(&smark); |
@@ -8365,7 +8380,7 @@ growstackstr(void) | |||
8365 | { | 8380 | { |
8366 | size_t len = stackblocksize(); | 8381 | size_t len = stackblocksize(); |
8367 | if (herefd >= 0 && len >= 1024) { | 8382 | if (herefd >= 0 && len >= 1024) { |
8368 | xwrite(herefd, stackblock(), len); | 8383 | bb_full_write(herefd, stackblock(), len); |
8369 | return stackblock(); | 8384 | return stackblock(); |
8370 | } | 8385 | } |
8371 | growstackblock(); | 8386 | growstackblock(); |
@@ -9030,21 +9045,26 @@ static void change_lc_ctype(const char *value) | |||
9030 | 9045 | ||
9031 | #endif | 9046 | #endif |
9032 | 9047 | ||
9048 | #ifdef CONFIG_ASH_RANDOM_SUPPORT | ||
9033 | /* Roughly copied from bash.. */ | 9049 | /* Roughly copied from bash.. */ |
9034 | static unsigned long rseed = 1; | ||
9035 | static char *get_random(const char *var) | ||
9036 | { | ||
9037 | char buf[255]; | ||
9038 | rseed = (rseed + getpid() + ((time_t)time((time_t *)0))); | ||
9039 | rseed = rseed * 1103515245 + 12345; | ||
9040 | sprintf(buf, "%d", (unsigned int)((rseed >> 16 & 32767))); | ||
9041 | return bb_xstrdup(buf); | ||
9042 | } | ||
9043 | |||
9044 | static void change_random(const char *value) | 9050 | static void change_random(const char *value) |
9045 | { | 9051 | { |
9046 | rseed = strtoul(value, (char **)NULL, 10); | 9052 | if(value == NULL) { |
9053 | /* "get", generate */ | ||
9054 | char buf[16]; | ||
9055 | |||
9056 | rseed = rseed * 1103515245 + 12345; | ||
9057 | sprintf(buf, "%d", (unsigned int)((rseed & 32767))); | ||
9058 | /* set without recursion */ | ||
9059 | setvar(vrandom.text, buf, VNOFUNC); | ||
9060 | vrandom.flags &= ~VNOFUNC; | ||
9061 | } else { | ||
9062 | /* set/reset */ | ||
9063 | rseed = strtoul(value, (char **)NULL, 10); | ||
9064 | } | ||
9047 | } | 9065 | } |
9066 | #endif | ||
9067 | |||
9048 | 9068 | ||
9049 | #ifdef CONFIG_ASH_GETOPTS | 9069 | #ifdef CONFIG_ASH_GETOPTS |
9050 | static int | 9070 | static int |
@@ -9234,10 +9254,10 @@ flushall(void) | |||
9234 | } | 9254 | } |
9235 | 9255 | ||
9236 | void | 9256 | void |
9237 | flushout(FILE *dest) | 9257 | flusherr(void) |
9238 | { | 9258 | { |
9239 | INTOFF; | 9259 | INTOFF; |
9240 | fflush(dest); | 9260 | fflush(stderr); |
9241 | INTON; | 9261 | INTON; |
9242 | } | 9262 | } |
9243 | 9263 | ||
@@ -9281,20 +9301,6 @@ fmtstr(char *outbuf, size_t length, const char *fmt, ...) | |||
9281 | } | 9301 | } |
9282 | 9302 | ||
9283 | 9303 | ||
9284 | /* | ||
9285 | * Version of write which resumes after a signal is caught. | ||
9286 | */ | ||
9287 | |||
9288 | static void | ||
9289 | xwrite(int fd, const void *p, size_t n) | ||
9290 | { | ||
9291 | ssize_t i; | ||
9292 | |||
9293 | do { | ||
9294 | i = bb_full_write(fd, p, n); | ||
9295 | } while (i < 0 && errno == EINTR); | ||
9296 | } | ||
9297 | |||
9298 | 9304 | ||
9299 | /* $NetBSD: parser.c,v 1.54 2002/11/24 22:35:42 christos Exp $ */ | 9305 | /* $NetBSD: parser.c,v 1.54 2002/11/24 22:35:42 christos Exp $ */ |
9300 | 9306 | ||
@@ -10951,7 +10957,7 @@ openhere(union node *redir) | |||
10951 | if (redir->type == NHERE) { | 10957 | if (redir->type == NHERE) { |
10952 | len = strlen(redir->nhere.doc->narg.text); | 10958 | len = strlen(redir->nhere.doc->narg.text); |
10953 | if (len <= PIPESIZE) { | 10959 | if (len <= PIPESIZE) { |
10954 | xwrite(pip[1], redir->nhere.doc->narg.text, len); | 10960 | bb_full_write(pip[1], redir->nhere.doc->narg.text, len); |
10955 | goto out; | 10961 | goto out; |
10956 | } | 10962 | } |
10957 | } | 10963 | } |
@@ -10965,7 +10971,7 @@ openhere(union node *redir) | |||
10965 | #endif | 10971 | #endif |
10966 | signal(SIGPIPE, SIG_DFL); | 10972 | signal(SIGPIPE, SIG_DFL); |
10967 | if (redir->type == NHERE) | 10973 | if (redir->type == NHERE) |
10968 | xwrite(pip[1], redir->nhere.doc->narg.text, len); | 10974 | bb_full_write(pip[1], redir->nhere.doc->narg.text, len); |
10969 | else | 10975 | else |
10970 | expandhere(redir->nhere.doc, pip[1]); | 10976 | expandhere(redir->nhere.doc, pip[1]); |
10971 | _exit(0); | 10977 | _exit(0); |
@@ -11998,10 +12004,13 @@ setvareq(char *s, int flags) | |||
11998 | flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1)); | 12004 | flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1)); |
11999 | vp = *findvar(vpp, s); | 12005 | vp = *findvar(vpp, s); |
12000 | if (vp) { | 12006 | if (vp) { |
12001 | if (vp->flags & VREADONLY) { | 12007 | if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) { |
12008 | const char *n; | ||
12009 | |||
12002 | if (flags & VNOSAVE) | 12010 | if (flags & VNOSAVE) |
12003 | free(s); | 12011 | free(s); |
12004 | error("%.*s: is read only", strchrnul(s, '=') - s, s); | 12012 | n = vp->text; |
12013 | error("%.*s: is read only", strchrnul(n, '=') - n, n); | ||
12005 | } | 12014 | } |
12006 | 12015 | ||
12007 | if (flags & VNOSET) | 12016 | if (flags & VNOSET) |
@@ -12058,19 +12067,20 @@ lookupvar(const char *name) | |||
12058 | { | 12067 | { |
12059 | struct var *v; | 12068 | struct var *v; |
12060 | 12069 | ||
12061 | if ((v = *findvar(hashvar(name), name)) && !(v->flags & (VUNSET|VDYNAMIC))) { | 12070 | if ((v = *findvar(hashvar(name), name))) { |
12062 | return strchrnul(v->text, '=') + 1; | 12071 | #ifdef DYNAMIC_VAR |
12063 | } | ||
12064 | |||
12065 | /* | 12072 | /* |
12066 | * Dynamic variables are implemented roughly the same way they are | 12073 | * Dynamic variables are implemented roughly the same way they are |
12067 | * in bash. Namely, they're "special" so long as they aren't unset. | 12074 | * in bash. Namely, they're "special" so long as they aren't unset. |
12068 | * As soon as they're unset, they're no longer dynamic, and dynamic | 12075 | * As soon as they're unset, they're no longer dynamic, and dynamic |
12069 | * lookup will no longer happen at that point. -- PFM. | 12076 | * lookup will no longer happen at that point. -- PFM. |
12070 | */ | 12077 | */ |
12071 | if (v && ((v->flags & VDYNAMIC))) | 12078 | if((v->flags & VDYNAMIC)) |
12072 | if (v->lookup_func) | 12079 | (*v->func)(NULL); |
12073 | return v->lookup_func(name); | 12080 | #endif |
12081 | if(!(v->flags & VUNSET)) | ||
12082 | return strchrnul(v->text, '=') + 1; | ||
12083 | } | ||
12074 | 12084 | ||
12075 | return NULL; | 12085 | return NULL; |
12076 | } | 12086 | } |
@@ -12346,8 +12356,9 @@ unsetvar(const char *s) | |||
12346 | retval = 1; | 12356 | retval = 1; |
12347 | if (flags & VREADONLY) | 12357 | if (flags & VREADONLY) |
12348 | goto out; | 12358 | goto out; |
12349 | if (flags & VDYNAMIC) | 12359 | #ifdef DYNAMIC_VAR |
12350 | vp->flags &= ~VDYNAMIC; | 12360 | vp->flags &= ~VDYNAMIC; |
12361 | #endif | ||
12351 | if (flags & VUNSET) | 12362 | if (flags & VUNSET) |
12352 | goto ok; | 12363 | goto ok; |
12353 | if ((flags & VSTRFIXED) == 0) { | 12364 | if ((flags & VSTRFIXED) == 0) { |