aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c112
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
331static 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);
1761struct var { 1769struct 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
1817static const struct { 1825static 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
1973static int
1974varequal(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 **
2028findvar(struct var **vpp, const char *name) 2030findvar(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 */