diff options
author | Ron Yorston <rmy@pobox.com> | 2018-12-14 15:27:54 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-12-14 17:41:29 +0000 |
commit | a236242374daf911a01e998fabb1cc1268b2be7b (patch) | |
tree | 5e30a868b8580a645f94003e27bf96d6ebcd0ee1 /shell | |
parent | 575581082befff0e049ef67fa36bbdd2ca737e29 (diff) | |
download | busybox-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.c | 86 |
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 | ||
2426 | static char * | ||
2427 | fix_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. */ |