aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-12-14 15:27:54 +0000
committerRon Yorston <rmy@pobox.com>2018-12-14 17:41:29 +0000
commita236242374daf911a01e998fabb1cc1268b2be7b (patch)
tree5e30a868b8580a645f94003e27bf96d6ebcd0ee1 /shell
parent575581082befff0e049ef67fa36bbdd2ca737e29 (diff)
downloadbusybox-w32-a236242374daf911a01e998fabb1cc1268b2be7b.tar.gz
busybox-w32-a236242374daf911a01e998fabb1cc1268b2be7b.tar.bz2
busybox-w32-a236242374daf911a01e998fabb1cc1268b2be7b.zip
win32: special treatment for PATH
The PATH shell variable is a special case. It can be exported to the environment where it might be interpreted by native applications which assume the separator is ';'. Hence: - require that the separator used in PATH is ';' - enforce this by intercepting calls to setvareq() that set PATH and adjusting its value if necessary. As a result of this the code to parse PATH can be simplified by replacing the hardcoded Unix ':' path separator by the platform- dependent macro PATH_SEP. The MANPATH variable is also required to use ';' as its separator but since it's less likely to be used this isn't enforced.
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c86
1 files changed, 61 insertions, 25 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 3bbfbd694..a659fd703 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2422,6 +2422,42 @@ bltinlookup(const char *name)
2422 return lookupvar(name); 2422 return lookupvar(name);
2423} 2423}
2424 2424
2425#if ENABLE_PLATFORM_MINGW32
2426static char *
2427fix_pathvar(const char *path)
2428{
2429 char *newpath = xstrdup(path);
2430 char *p;
2431 int modified = FALSE;
2432
2433 p = newpath + 5;
2434 while (*p) {
2435 if (*p != ':' && *p != ';') {
2436 /* skip drive */
2437 if (isalpha(*p) && p[1] == ':')
2438 p += 2;
2439 /* skip through path component */
2440 for (; *p != '\0' && *p != ':' && *p != ';'; ++p)
2441 continue;
2442 }
2443 /* *p is ':', ';' or '\0' here */
2444 if (*p == ':') {
2445 *p++ = ';';
2446 modified = TRUE;
2447 }
2448 else if (*p == ';') {
2449 ++p;
2450 }
2451 }
2452
2453 if (!modified) {
2454 free(newpath);
2455 newpath = NULL;
2456 }
2457 return newpath;
2458}
2459#endif
2460
2425/* 2461/*
2426 * Same as setvar except that the variable and value are passed in 2462 * Same as setvar except that the variable and value are passed in
2427 * the first argument as name=value. Since the first argument will 2463 * the first argument as name=value. Since the first argument will
@@ -2434,6 +2470,19 @@ setvareq(char *s, int flags)
2434{ 2470{
2435 struct var *vp, **vpp; 2471 struct var *vp, **vpp;
2436 2472
2473#if ENABLE_PLATFORM_MINGW32
2474 if (strncmp(s, "PATH=", 5) == 0) {
2475 char *newpath = fix_pathvar(s);
2476 if (newpath) {
2477 if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE)
2478 free(s);
2479 flags |= VNOSAVE;
2480 flags &= ~(VTEXTFIXED|VSTACK);
2481 s = newpath;
2482 }
2483 }
2484#endif
2485
2437 vpp = hashvar(s); 2486 vpp = hashvar(s);
2438 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1)); 2487 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
2439 vpp = findvar(vpp, s); 2488 vpp = findvar(vpp, s);
@@ -2646,18 +2695,8 @@ path_advance(const char **path, const char *name)
2646 if (*path == NULL) 2695 if (*path == NULL)
2647 return NULL; 2696 return NULL;
2648 start = *path; 2697 start = *path;
2649#if ENABLE_PLATFORM_MINGW32 2698 for (p = start; *p && *p != PATH_SEP && *p != '%'; p++)
2650 p = next_path_sep(start);
2651 q = strchr(start, '%');
2652 if ((p && q && q < p) || (!p && q))
2653 p = q;
2654 if (!p)
2655 for (p = start; *p; p++)
2656 continue;
2657#else
2658 for (p = start; *p && *p != ':' && *p != '%'; p++)
2659 continue; 2699 continue;
2660#endif
2661 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */ 2700 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
2662 2701
2663 /* reserve space for suffix on WIN32 */ 2702 /* reserve space for suffix on WIN32 */
@@ -2672,19 +2711,10 @@ path_advance(const char **path, const char *name)
2672 pathopt = NULL; 2711 pathopt = NULL;
2673 if (*p == '%') { 2712 if (*p == '%') {
2674 pathopt = ++p; 2713 pathopt = ++p;
2675#if ENABLE_PLATFORM_MINGW32 2714 while (*p && *p != PATH_SEP)
2676 p = next_path_sep(start);
2677
2678 /* *p != ':' and '*' would suffice */
2679 if (!p)
2680 p = pathopt - 1;
2681#else
2682 while (*p && *p != ':')
2683 p++; 2715 p++;
2684#endif
2685 } 2716 }
2686 if (*p == ':' || 2717 if (*p == PATH_SEP)
2687 (ENABLE_PLATFORM_MINGW32 && *p == ';'))
2688 *path = p + 1; 2718 *path = p + 1;
2689 else 2719 else
2690 *path = NULL; 2720 *path = NULL;
@@ -8733,8 +8763,8 @@ changepath(const char *new)
8733 for (;;) { 8763 for (;;) {
8734 if (*old != *new) { 8764 if (*old != *new) {
8735 firstchange = idx; 8765 firstchange = idx;
8736 if ((*old == '\0' && *new == ':') 8766 if ((*old == '\0' && *new == PATH_SEP)
8737 || (*old == ':' && *new == '\0') 8767 || (*old == PATH_SEP && *new == '\0')
8738 ) { 8768 ) {
8739 firstchange++; 8769 firstchange++;
8740 } 8770 }
@@ -8744,7 +8774,7 @@ changepath(const char *new)
8744 break; 8774 break;
8745 if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin")) 8775 if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin"))
8746 idx_bltin = idx; 8776 idx_bltin = idx;
8747 if (*new == ':') 8777 if (*new == PATH_SEP)
8748 idx++; 8778 idx++;
8749 new++; 8779 new++;
8750 old++; 8780 old++;
@@ -10585,7 +10615,13 @@ evalcommand(union node *cmd, int flags)
10585 */ 10615 */
10586 p = (*spp)->text; 10616 p = (*spp)->text;
10587 if (varcmp(p, path) == 0) 10617 if (varcmp(p, path) == 0)
10618#if !ENABLE_PLATFORM_MINGW32
10588 path = p; 10619 path = p;
10620#else
10621 /* fix_pathvar may have modified the value of the local
10622 * variable so we look it up again */
10623 path = vpath.var_text;
10624#endif
10589 } 10625 }
10590 10626
10591 /* Print the command if xflag is set. */ 10627 /* Print the command if xflag is set. */