diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 112 |
1 files changed, 57 insertions, 55 deletions
diff --git a/shell/ash.c b/shell/ash.c index d6838f82c..13072cd04 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -328,6 +328,14 @@ static int isdigit_str9(const char *str) | |||
328 | return (*str == '\0'); | 328 | return (*str == '\0'); |
329 | } | 329 | } |
330 | 330 | ||
331 | static const char *var_end(const char *var) | ||
332 | { | ||
333 | while (*var) | ||
334 | if (*var++ == '=') | ||
335 | break; | ||
336 | return var; | ||
337 | } | ||
338 | |||
331 | 339 | ||
332 | /* ============ Interrupts / exceptions */ | 340 | /* ============ Interrupts / exceptions */ |
333 | /* | 341 | /* |
@@ -1761,8 +1769,8 @@ static void FAST_FUNC getoptsreset(const char *value); | |||
1761 | struct var { | 1769 | struct var { |
1762 | struct var *next; /* next entry in hash list */ | 1770 | struct var *next; /* next entry in hash list */ |
1763 | int flags; /* flags are defined above */ | 1771 | int flags; /* flags are defined above */ |
1764 | const char *text; /* name=value */ | 1772 | const char *var_text; /* name=value */ |
1765 | void (*func)(const char *) FAST_FUNC; /* function to be called when */ | 1773 | void (*var_func)(const char *) FAST_FUNC; /* function to be called when */ |
1766 | /* the variable gets set/unset */ | 1774 | /* the variable gets set/unset */ |
1767 | }; | 1775 | }; |
1768 | 1776 | ||
@@ -1816,13 +1824,13 @@ static void change_random(const char *) FAST_FUNC; | |||
1816 | 1824 | ||
1817 | static const struct { | 1825 | static const struct { |
1818 | int flags; | 1826 | int flags; |
1819 | const char *text; | 1827 | const char *var_text; |
1820 | void (*func)(const char *) FAST_FUNC; | 1828 | void (*var_func)(const char *) FAST_FUNC; |
1821 | } varinit_data[] = { | 1829 | } varinit_data[] = { |
1822 | { VSTRFIXED|VTEXTFIXED , defifsvar , NULL }, | 1830 | { VSTRFIXED|VTEXTFIXED , defifsvar , NULL }, |
1823 | #if ENABLE_ASH_MAIL | 1831 | #if ENABLE_ASH_MAIL |
1824 | { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0" , changemail }, | 1832 | { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL" , changemail }, |
1825 | { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail }, | 1833 | { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH" , changemail }, |
1826 | #endif | 1834 | #endif |
1827 | { VSTRFIXED|VTEXTFIXED , bb_PATH_root_path, changepath }, | 1835 | { VSTRFIXED|VTEXTFIXED , bb_PATH_root_path, changepath }, |
1828 | { VSTRFIXED|VTEXTFIXED , "PS1=$ " , NULL }, | 1836 | { VSTRFIXED|VTEXTFIXED , "PS1=$ " , NULL }, |
@@ -1832,14 +1840,14 @@ static const struct { | |||
1832 | { VSTRFIXED|VTEXTFIXED , "OPTIND=1" , getoptsreset }, | 1840 | { VSTRFIXED|VTEXTFIXED , "OPTIND=1" , getoptsreset }, |
1833 | #endif | 1841 | #endif |
1834 | #if ENABLE_ASH_RANDOM_SUPPORT | 1842 | #if ENABLE_ASH_RANDOM_SUPPORT |
1835 | { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM\0", change_random }, | 1843 | { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random }, |
1836 | #endif | 1844 | #endif |
1837 | #if ENABLE_LOCALE_SUPPORT | 1845 | #if ENABLE_LOCALE_SUPPORT |
1838 | { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL\0" , change_lc_all }, | 1846 | { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL" , change_lc_all }, |
1839 | { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE\0", change_lc_ctype }, | 1847 | { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE" , change_lc_ctype }, |
1840 | #endif | 1848 | #endif |
1841 | #if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1849 | #if ENABLE_FEATURE_EDITING_SAVEHISTORY |
1842 | { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE\0", NULL }, | 1850 | { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE" , NULL }, |
1843 | #endif | 1851 | #endif |
1844 | }; | 1852 | }; |
1845 | 1853 | ||
@@ -1866,9 +1874,9 @@ extern struct globals_var *const ash_ptr_to_globals_var; | |||
1866 | (*(struct globals_var**)&ash_ptr_to_globals_var) = xzalloc(sizeof(G_var)); \ | 1874 | (*(struct globals_var**)&ash_ptr_to_globals_var) = xzalloc(sizeof(G_var)); \ |
1867 | barrier(); \ | 1875 | barrier(); \ |
1868 | for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \ | 1876 | for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \ |
1869 | varinit[i].flags = varinit_data[i].flags; \ | 1877 | varinit[i].flags = varinit_data[i].flags; \ |
1870 | varinit[i].text = varinit_data[i].text; \ | 1878 | varinit[i].var_text = varinit_data[i].var_text; \ |
1871 | varinit[i].func = varinit_data[i].func; \ | 1879 | varinit[i].var_func = varinit_data[i].var_func; \ |
1872 | } \ | 1880 | } \ |
1873 | } while (0) | 1881 | } while (0) |
1874 | 1882 | ||
@@ -1899,19 +1907,19 @@ extern struct globals_var *const ash_ptr_to_globals_var; | |||
1899 | * They have to skip over the name. They return the null string | 1907 | * They have to skip over the name. They return the null string |
1900 | * for unset variables. | 1908 | * for unset variables. |
1901 | */ | 1909 | */ |
1902 | #define ifsval() (vifs.text + 4) | 1910 | #define ifsval() (vifs.var_text + 4) |
1903 | #define ifsset() ((vifs.flags & VUNSET) == 0) | 1911 | #define ifsset() ((vifs.flags & VUNSET) == 0) |
1904 | #if ENABLE_ASH_MAIL | 1912 | #if ENABLE_ASH_MAIL |
1905 | # define mailval() (vmail.text + 5) | 1913 | # define mailval() (vmail.var_text + 5) |
1906 | # define mpathval() (vmpath.text + 9) | 1914 | # define mpathval() (vmpath.var_text + 9) |
1907 | # define mpathset() ((vmpath.flags & VUNSET) == 0) | 1915 | # define mpathset() ((vmpath.flags & VUNSET) == 0) |
1908 | #endif | 1916 | #endif |
1909 | #define pathval() (vpath.text + 5) | 1917 | #define pathval() (vpath.var_text + 5) |
1910 | #define ps1val() (vps1.text + 4) | 1918 | #define ps1val() (vps1.var_text + 4) |
1911 | #define ps2val() (vps2.text + 4) | 1919 | #define ps2val() (vps2.var_text + 4) |
1912 | #define ps4val() (vps4.text + 4) | 1920 | #define ps4val() (vps4.var_text + 4) |
1913 | #if ENABLE_ASH_GETOPTS | 1921 | #if ENABLE_ASH_GETOPTS |
1914 | # define optindval() (voptind.text + 7) | 1922 | # define optindval() (voptind.var_text + 7) |
1915 | #endif | 1923 | #endif |
1916 | 1924 | ||
1917 | 1925 | ||
@@ -1970,12 +1978,6 @@ varcmp(const char *p, const char *q) | |||
1970 | return c - d; | 1978 | return c - d; |
1971 | } | 1979 | } |
1972 | 1980 | ||
1973 | static int | ||
1974 | varequal(const char *a, const char *b) | ||
1975 | { | ||
1976 | return !varcmp(a, b); | ||
1977 | } | ||
1978 | |||
1979 | /* | 1981 | /* |
1980 | * Find the appropriate entry in the hash table from the name. | 1982 | * Find the appropriate entry in the hash table from the name. |
1981 | */ | 1983 | */ |
@@ -2010,15 +2012,15 @@ initvar(void) | |||
2010 | * PS1 depends on uid | 2012 | * PS1 depends on uid |
2011 | */ | 2013 | */ |
2012 | #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT | 2014 | #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT |
2013 | vps1.text = "PS1=\\w \\$ "; | 2015 | vps1.var_text = "PS1=\\w \\$ "; |
2014 | #else | 2016 | #else |
2015 | if (!geteuid()) | 2017 | if (!geteuid()) |
2016 | vps1.text = "PS1=# "; | 2018 | vps1.var_text = "PS1=# "; |
2017 | #endif | 2019 | #endif |
2018 | vp = varinit; | 2020 | vp = varinit; |
2019 | end = vp + ARRAY_SIZE(varinit); | 2021 | end = vp + ARRAY_SIZE(varinit); |
2020 | do { | 2022 | do { |
2021 | vpp = hashvar(vp->text); | 2023 | vpp = hashvar(vp->var_text); |
2022 | vp->next = *vpp; | 2024 | vp->next = *vpp; |
2023 | *vpp = vp; | 2025 | *vpp = vp; |
2024 | } while (++vp < end); | 2026 | } while (++vp < end); |
@@ -2028,7 +2030,7 @@ static struct var ** | |||
2028 | findvar(struct var **vpp, const char *name) | 2030 | findvar(struct var **vpp, const char *name) |
2029 | { | 2031 | { |
2030 | for (; *vpp; vpp = &(*vpp)->next) { | 2032 | for (; *vpp; vpp = &(*vpp)->next) { |
2031 | if (varequal((*vpp)->text, name)) { | 2033 | if (varcmp((*vpp)->var_text, name) == 0) { |
2032 | break; | 2034 | break; |
2033 | } | 2035 | } |
2034 | } | 2036 | } |
@@ -2052,11 +2054,11 @@ lookupvar(const char *name) | |||
2052 | * As soon as they're unset, they're no longer dynamic, and dynamic | 2054 | * As soon as they're unset, they're no longer dynamic, and dynamic |
2053 | * lookup will no longer happen at that point. -- PFM. | 2055 | * lookup will no longer happen at that point. -- PFM. |
2054 | */ | 2056 | */ |
2055 | if ((v->flags & VDYNAMIC)) | 2057 | if (v->flags & VDYNAMIC) |
2056 | (*v->func)(NULL); | 2058 | v->var_func(NULL); |
2057 | #endif | 2059 | #endif |
2058 | if (!(v->flags & VUNSET)) | 2060 | if (!(v->flags & VUNSET)) |
2059 | return strchrnul(v->text, '=') + 1; | 2061 | return var_end(v->var_text); |
2060 | } | 2062 | } |
2061 | return NULL; | 2063 | return NULL; |
2062 | } | 2064 | } |
@@ -2070,8 +2072,8 @@ bltinlookup(const char *name) | |||
2070 | struct strlist *sp; | 2072 | struct strlist *sp; |
2071 | 2073 | ||
2072 | for (sp = cmdenviron; sp; sp = sp->next) { | 2074 | for (sp = cmdenviron; sp; sp = sp->next) { |
2073 | if (varequal(sp->text, name)) | 2075 | if (varcmp(sp->text, name) == 0) |
2074 | return strchrnul(sp->text, '=') + 1; | 2076 | return var_end(sp->text); |
2075 | } | 2077 | } |
2076 | return lookupvar(name); | 2078 | return lookupvar(name); |
2077 | } | 2079 | } |
@@ -2097,24 +2099,24 @@ setvareq(char *s, int flags) | |||
2097 | 2099 | ||
2098 | if (flags & VNOSAVE) | 2100 | if (flags & VNOSAVE) |
2099 | free(s); | 2101 | free(s); |
2100 | n = vp->text; | 2102 | n = vp->var_text; |
2101 | ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n); | 2103 | ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n); |
2102 | } | 2104 | } |
2103 | 2105 | ||
2104 | if (flags & VNOSET) | 2106 | if (flags & VNOSET) |
2105 | return; | 2107 | return; |
2106 | 2108 | ||
2107 | if (vp->func && (flags & VNOFUNC) == 0) | 2109 | if (vp->var_func && !(flags & VNOFUNC)) |
2108 | (*vp->func)(strchrnul(s, '=') + 1); | 2110 | vp->var_func(var_end(s)); |
2109 | 2111 | ||
2110 | if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) | 2112 | if (!(vp->flags & (VTEXTFIXED|VSTACK))) |
2111 | free((char*)vp->text); | 2113 | free((char*)vp->var_text); |
2112 | 2114 | ||
2113 | flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET); | 2115 | flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET); |
2114 | } else { | 2116 | } else { |
2117 | /* variable s is not found */ | ||
2115 | if (flags & VNOSET) | 2118 | if (flags & VNOSET) |
2116 | return; | 2119 | return; |
2117 | /* not found */ | ||
2118 | vp = ckzalloc(sizeof(*vp)); | 2120 | vp = ckzalloc(sizeof(*vp)); |
2119 | vp->next = *vpp; | 2121 | vp->next = *vpp; |
2120 | /*vp->func = NULL; - ckzalloc did it */ | 2122 | /*vp->func = NULL; - ckzalloc did it */ |
@@ -2122,7 +2124,7 @@ setvareq(char *s, int flags) | |||
2122 | } | 2124 | } |
2123 | if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE))) | 2125 | if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE))) |
2124 | s = ckstrdup(s); | 2126 | s = ckstrdup(s); |
2125 | vp->text = s; | 2127 | vp->var_text = s; |
2126 | vp->flags = flags; | 2128 | vp->flags = flags; |
2127 | } | 2129 | } |
2128 | 2130 | ||
@@ -2220,7 +2222,7 @@ unsetvar(const char *s) | |||
2220 | if ((flags & VSTRFIXED) == 0) { | 2222 | if ((flags & VSTRFIXED) == 0) { |
2221 | INT_OFF; | 2223 | INT_OFF; |
2222 | if ((flags & (VTEXTFIXED|VSTACK)) == 0) | 2224 | if ((flags & (VTEXTFIXED|VSTACK)) == 0) |
2223 | free((char*)vp->text); | 2225 | free((char*)vp->var_text); |
2224 | *vpp = vp->next; | 2226 | *vpp = vp->next; |
2225 | free(vp); | 2227 | free(vp); |
2226 | INT_ON; | 2228 | INT_ON; |
@@ -2272,7 +2274,7 @@ listvars(int on, int off, char ***end) | |||
2272 | if ((vp->flags & mask) == on) { | 2274 | if ((vp->flags & mask) == on) { |
2273 | if (ep == stackstrend()) | 2275 | if (ep == stackstrend()) |
2274 | ep = growstackstr(); | 2276 | ep = growstackstr(); |
2275 | *ep++ = (char *) vp->text; | 2277 | *ep++ = (char*)vp->var_text; |
2276 | } | 2278 | } |
2277 | } | 2279 | } |
2278 | } while (++vpp < vartab + VTABSIZE); | 2280 | } while (++vpp < vartab + VTABSIZE); |
@@ -6912,7 +6914,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6912 | var = p; | 6914 | var = p; |
6913 | easy = (!quoted || (*var == '@' && shellparam.nparam)); | 6915 | easy = (!quoted || (*var == '@' && shellparam.nparam)); |
6914 | startloc = expdest - (char *)stackblock(); | 6916 | startloc = expdest - (char *)stackblock(); |
6915 | p = strchr(p, '=') + 1; | 6917 | p = strchr(p, '=') + 1; //TODO: use var_end(p)? |
6916 | 6918 | ||
6917 | again: | 6919 | again: |
6918 | varlen = varvalue(var, varflags, flags, var_str_list); | 6920 | varlen = varvalue(var, varflags, flags, var_str_list); |
@@ -9067,14 +9069,14 @@ poplocalvars(void) | |||
9067 | free((char*)lvp->text); | 9069 | free((char*)lvp->text); |
9068 | optschanged(); | 9070 | optschanged(); |
9069 | } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { | 9071 | } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { |
9070 | unsetvar(vp->text); | 9072 | unsetvar(vp->var_text); |
9071 | } else { | 9073 | } else { |
9072 | if (vp->func) | 9074 | if (vp->var_func) |
9073 | (*vp->func)(strchrnul(lvp->text, '=') + 1); | 9075 | vp->var_func(var_end(lvp->text)); |
9074 | if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) | 9076 | if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) |
9075 | free((char*)vp->text); | 9077 | free((char*)vp->var_text); |
9076 | vp->flags = lvp->flags; | 9078 | vp->flags = lvp->flags; |
9077 | vp->text = lvp->text; | 9079 | vp->var_text = lvp->text; |
9078 | } | 9080 | } |
9079 | free(lvp); | 9081 | free(lvp); |
9080 | } | 9082 | } |
@@ -9193,7 +9195,7 @@ mklocal(char *name) | |||
9193 | vp = *vpp; /* the new variable */ | 9195 | vp = *vpp; /* the new variable */ |
9194 | lvp->flags = VUNSET; | 9196 | lvp->flags = VUNSET; |
9195 | } else { | 9197 | } else { |
9196 | lvp->text = vp->text; | 9198 | lvp->text = vp->var_text; |
9197 | lvp->flags = vp->flags; | 9199 | lvp->flags = vp->flags; |
9198 | vp->flags |= VSTRFIXED|VTEXTFIXED; | 9200 | vp->flags |= VSTRFIXED|VTEXTFIXED; |
9199 | if (eq) | 9201 | if (eq) |
@@ -9517,7 +9519,7 @@ evalcommand(union node *cmd, int flags) | |||
9517 | expredir(cmd->ncmd.redirect); | 9519 | expredir(cmd->ncmd.redirect); |
9518 | status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2); | 9520 | status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2); |
9519 | 9521 | ||
9520 | path = vpath.text; | 9522 | path = vpath.var_text; |
9521 | for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { | 9523 | for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { |
9522 | struct strlist **spp; | 9524 | struct strlist **spp; |
9523 | char *p; | 9525 | char *p; |
@@ -9530,7 +9532,7 @@ evalcommand(union node *cmd, int flags) | |||
9530 | * is present | 9532 | * is present |
9531 | */ | 9533 | */ |
9532 | p = (*spp)->text; | 9534 | p = (*spp)->text; |
9533 | if (varequal(p, path)) | 9535 | if (varcmp(p, path) == 0) |
9534 | path = p; | 9536 | path = p; |
9535 | } | 9537 | } |
9536 | 9538 | ||
@@ -10578,7 +10580,7 @@ change_random(const char *value) | |||
10578 | /* "get", generate */ | 10580 | /* "get", generate */ |
10579 | t = next_random(&random_gen); | 10581 | t = next_random(&random_gen); |
10580 | /* set without recursion */ | 10582 | /* set without recursion */ |
10581 | setvar(vrandom.text, utoa(t), VNOFUNC); | 10583 | setvar(vrandom.var_text, utoa(t), VNOFUNC); |
10582 | vrandom.flags &= ~VNOFUNC; | 10584 | vrandom.flags &= ~VNOFUNC; |
10583 | } else { | 10585 | } else { |
10584 | /* set/reset */ | 10586 | /* set/reset */ |