summaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-10-13 14:37:51 +0100
committerRon Yorston <rmy@pobox.com>2021-10-13 14:37:51 +0100
commit0ecf1aea459571b48dc68ddc2b7b9265740fa960 (patch)
tree491d6184a44b8b525a4ca35759d622aecd7f6344 /shell/ash.c
parent4859ddcb20616718efbea12c6bf8b27c469b68de (diff)
parentaaf3d5ba74c5da97ff80b61f30cb8dd225d39096 (diff)
downloadbusybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.gz
busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.bz2
busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c68
1 files changed, 31 insertions, 37 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 9214982c1..98da20f8a 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -351,19 +351,6 @@ typedef long arith_t;
351# error "Do not even bother, ash will not run on NOMMU machine" 351# error "Do not even bother, ash will not run on NOMMU machine"
352#endif 352#endif
353 353
354/* We use a trick to have more optimized code (fewer pointer reloads):
355 * ash.c: extern struct globals *const ash_ptr_to_globals;
356 * ash_ptr_hack.c: struct globals *ash_ptr_to_globals;
357 * This way, compiler in ash.c knows the pointer can not change.
358 *
359 * However, this may break on weird arches or toolchains. In this case,
360 * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable
361 * this optimization.
362 */
363#ifndef BB_GLOBAL_CONST
364# define BB_GLOBAL_CONST const
365#endif
366
367#if ENABLE_PLATFORM_MINGW32 354#if ENABLE_PLATFORM_MINGW32
368# define FORKSHELL_DEBUG 0 355# define FORKSHELL_DEBUG 0
369 356
@@ -693,8 +680,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
693#endif 680#endif
694 681
695#define INIT_G_misc() do { \ 682#define INIT_G_misc() do { \
696 (*(struct globals_misc**)not_const_pp(&ash_ptr_to_globals_misc)) = xzalloc(sizeof(G_misc)); \ 683 XZALLOC_CONST_PTR(&ash_ptr_to_globals_misc, sizeof(G_misc)); \
697 barrier(); \
698 savestatus = -1; \ 684 savestatus = -1; \
699 curdir = nullstr; \ 685 curdir = nullstr; \
700 physdir = nullstr; \ 686 physdir = nullstr; \
@@ -1783,8 +1769,7 @@ extern struct globals_memstack *BB_GLOBAL_CONST ash_ptr_to_globals_memstack;
1783#define g_stacknleft (G_memstack.g_stacknleft) 1769#define g_stacknleft (G_memstack.g_stacknleft)
1784#define stackbase (G_memstack.stackbase ) 1770#define stackbase (G_memstack.stackbase )
1785#define INIT_G_memstack() do { \ 1771#define INIT_G_memstack() do { \
1786 (*(struct globals_memstack**)not_const_pp(&ash_ptr_to_globals_memstack)) = xzalloc(sizeof(G_memstack)); \ 1772 XZALLOC_CONST_PTR(&ash_ptr_to_globals_memstack, sizeof(G_memstack)); \
1787 barrier(); \
1788 g_stackp = &stackbase; \ 1773 g_stackp = &stackbase; \
1789 g_stacknxt = stackbase.space; \ 1774 g_stacknxt = stackbase.space; \
1790 g_stacknleft = MINSIZE; \ 1775 g_stacknleft = MINSIZE; \
@@ -2445,8 +2430,7 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
2445#endif 2430#endif
2446#define INIT_G_var() do { \ 2431#define INIT_G_var() do { \
2447 unsigned i; \ 2432 unsigned i; \
2448 (*(struct globals_var**)not_const_pp(&ash_ptr_to_globals_var)) = xzalloc(sizeof(G_var)); \ 2433 XZALLOC_CONST_PTR(&ash_ptr_to_globals_var, sizeof(G_var)); \
2449 barrier(); \
2450 for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \ 2434 for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
2451 varinit[i].flags = varinit_data[i].flags; \ 2435 varinit[i].flags = varinit_data[i].flags; \
2452 varinit[i].var_text = varinit_data[i].var_text; \ 2436 varinit[i].var_text = varinit_data[i].var_text; \
@@ -7840,14 +7824,19 @@ subevalvar(char *start, char *str, int strloc,
7840 if ((unsigned)len > (orig_len - pos)) 7824 if ((unsigned)len > (orig_len - pos))
7841 len = orig_len - pos; 7825 len = orig_len - pos;
7842 7826
7843 for (vstr = startp; pos; vstr++, pos--) { 7827 if (!quotes) {
7844 if (quotes && (unsigned char)*vstr == CTLESC) 7828 loc = mempcpy(startp, startp + pos, len);
7829 } else {
7830 for (vstr = startp; pos != 0; pos--) {
7831 if ((unsigned char)*vstr == CTLESC)
7832 vstr++;
7845 vstr++; 7833 vstr++;
7846 } 7834 }
7847 for (loc = startp; len; len--) { 7835 for (loc = startp; len != 0; len--) {
7848 if (quotes && (unsigned char)*vstr == CTLESC) 7836 if ((unsigned char)*vstr == CTLESC)
7837 *loc++ = *vstr++;
7849 *loc++ = *vstr++; 7838 *loc++ = *vstr++;
7850 *loc++ = *vstr++; 7839 }
7851 } 7840 }
7852 *loc = '\0'; 7841 *loc = '\0';
7853 goto out; 7842 goto out;
@@ -7901,7 +7890,7 @@ subevalvar(char *start, char *str, int strloc,
7901#if BASH_PATTERN_SUBST 7890#if BASH_PATTERN_SUBST
7902 workloc = expdest - (char *)stackblock(); 7891 workloc = expdest - (char *)stackblock();
7903 if (subtype == VSREPLACE || subtype == VSREPLACEALL) { 7892 if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
7904 size_t no_meta_len; 7893 size_t no_meta_len, first_escaped;
7905 int len; 7894 int len;
7906 char *idx, *end; 7895 char *idx, *end;
7907 7896
@@ -7919,28 +7908,34 @@ subevalvar(char *start, char *str, int strloc,
7919 if (str[0] == '\0') 7908 if (str[0] == '\0')
7920 goto out1; 7909 goto out1;
7921 7910
7922 no_meta_len = (ENABLE_ASH_OPTIMIZE_FOR_SIZE || strpbrk(str, "*?[\\")) ? 0 : strlen(str); 7911 first_escaped = (str[0] == '\\' && str[1]);
7912 /* "first_escaped" trick allows to treat e.g. "\*no_glob_chars"
7913 * as literal too (as it is semi-common, and easy to accomodate
7914 * by just using str + 1).
7915 */
7916 no_meta_len = strpbrk(str + first_escaped * 2, "*?[\\") ? 0 : strlen(str);
7923 len = 0; 7917 len = 0;
7924 idx = startp; 7918 idx = startp;
7925 end = str - 1; 7919 end = str - 1;
7926 while (idx <= end) { 7920 while (idx <= end) {
7927 try_to_match: 7921 try_to_match:
7928 if (no_meta_len == 0) { 7922 if (no_meta_len == 0) {
7929 /* pattern has meta chars, have to glob; or ENABLE_ASH_OPTIMIZE_FOR_SIZE */ 7923 /* pattern has meta chars, have to glob */
7930 loc = scanright(idx, rmesc, rmescend, str, quotes, /*match_at_start:*/ 1); 7924 loc = scanright(idx, rmesc, rmescend, str, quotes, /*match_at_start:*/ 1);
7931 } else { 7925 } else {
7932 /* Testcase for very slow replace (performs about 22k replaces): 7926 /* Testcase for very slow replace (performs about 22k replaces):
7933 * x=:::::::::::::::::::::: 7927 * x=::::::::::::::::::::::
7934 * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} 7928 * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x}
7935 * echo "${x//:/|}" 7929 * echo "${x//:/|}"
7930 * To test "first_escaped" logic, replace : with *.
7936 */ 7931 */
7937 if (strncmp(rmesc, str, no_meta_len) != 0) 7932 if (strncmp(rmesc, str + first_escaped, no_meta_len - first_escaped) != 0)
7938 goto no_match; 7933 goto no_match;
7939 loc = idx; 7934 loc = idx;
7940 if (!quotes) { 7935 if (!quotes) {
7941 loc += no_meta_len; 7936 loc += no_meta_len - first_escaped;
7942 } else { 7937 } else {
7943 size_t n = no_meta_len; 7938 size_t n = no_meta_len - first_escaped;
7944 do { 7939 do {
7945 if ((unsigned char)*loc == CTLESC) 7940 if ((unsigned char)*loc == CTLESC)
7946 loc++; 7941 loc++;
@@ -11811,14 +11806,14 @@ static void freestrings(struct strpush *sp)
11811 INT_OFF; 11806 INT_OFF;
11812 do { 11807 do {
11813 struct strpush *psp; 11808 struct strpush *psp;
11814 11809#if ENABLE_ASH_ALIAS
11815 if (sp->ap) { 11810 if (sp->ap) {
11816 sp->ap->flag &= ~ALIASINUSE; 11811 sp->ap->flag &= ~ALIASINUSE;
11817 if (sp->ap->flag & ALIASDEAD) { 11812 if (sp->ap->flag & ALIASDEAD) {
11818 unalias(sp->ap->name); 11813 unalias(sp->ap->name);
11819 } 11814 }
11820 } 11815 }
11821 11816#endif
11822 psp = sp; 11817 psp = sp;
11823 sp = sp->spfree; 11818 sp = sp->spfree;
11824 11819
@@ -15497,7 +15492,7 @@ init(void)
15497 15492
15498 15493
15499//usage:#define ash_trivial_usage 15494//usage:#define ash_trivial_usage
15500//usage: "[-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]" 15495//usage: "[-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 ARGS] | FILE ARGS | -s ARGS]"
15501//////// comes from ^^^^^^^^^^optletters 15496//////// comes from ^^^^^^^^^^optletters
15502//usage:#define ash_full_usage "\n\n" 15497//usage:#define ash_full_usage "\n\n"
15503//usage: "Unix shell interpreter" 15498//usage: "Unix shell interpreter"
@@ -15764,13 +15759,12 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
15764 } 15759 }
15765 state2: 15760 state2:
15766 state = 3; 15761 state = 3;
15767 if ( 15762 if (iflag
15768#if ENABLE_PLATFORM_POSIX 15763#if ENABLE_PLATFORM_POSIX
15769#ifndef linux 15764#ifndef linux
15770 getuid() == geteuid() && getgid() == getegid() && 15765 && getuid() == geteuid() && getgid() == getegid()
15771#endif 15766#endif
15772#endif 15767#endif
15773 iflag
15774 ) { 15768 ) {
15775 const char *shinit = lookupvar("ENV"); 15769 const char *shinit = lookupvar("ENV");
15776 if (shinit != NULL && *shinit != '\0') 15770 if (shinit != NULL && *shinit != '\0')