diff options
author | Ron Yorston <rmy@pobox.com> | 2023-06-21 08:48:57 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-06-21 08:48:57 +0100 |
commit | 3e73f1bd10d208a6a5636fdae632a58e892ad42a (patch) | |
tree | 7ca372b7d163fb0ae47d2bf89b5b8b9ff377c06c | |
parent | 29f13acfb2d3818592d93590aa06de3c4f169b42 (diff) | |
download | busybox-w32-3e73f1bd10d208a6a5636fdae632a58e892ad42a.tar.gz busybox-w32-3e73f1bd10d208a6a5636fdae632a58e892ad42a.tar.bz2 busybox-w32-3e73f1bd10d208a6a5636fdae632a58e892ad42a.zip |
ash: standardise treatment of winxp option
Although 'winxp' is a shell option it could only be set with '-X'
on the command line.
Fully implement 'winxp' so it can also be set within the shell by
'set -o winxp' and 'set +o winxp'. '-X' no longer needs to be the
first option on the command line.
Track which shell variables have been imported from a native Windows
environment so only those are affected when 'winxp' is changed. The
tracking persists in a subshell but is lost when shell variables are
exported to the environment so 'set -/+o winxp' is ineffective in a
child shell.
Costs 48-52 bytes.
(GitHub issue #322)
-rw-r--r-- | shell/ash.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/shell/ash.c b/shell/ash.c index 19026fb55..17af816d4 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2355,6 +2355,9 @@ struct localvar { | |||
2355 | #else | 2355 | #else |
2356 | # define VDYNAMIC 0 | 2356 | # define VDYNAMIC 0 |
2357 | #endif | 2357 | #endif |
2358 | #if ENABLE_PLATFORM_MINGW32 | ||
2359 | # define VIMPORT 0x400 /* variable was imported from environment */ | ||
2360 | #endif | ||
2358 | 2361 | ||
2359 | 2362 | ||
2360 | /* Need to be before varinit_data[] */ | 2363 | /* Need to be before varinit_data[] */ |
@@ -2963,6 +2966,36 @@ listvars(int on, int off, struct strlist *lp, char ***end) | |||
2963 | return grabstackstr(ep); | 2966 | return grabstackstr(ep); |
2964 | } | 2967 | } |
2965 | 2968 | ||
2969 | #if ENABLE_PLATFORM_MINGW32 | ||
2970 | /* Adjust directory separator in variables imported from the environment */ | ||
2971 | static void | ||
2972 | setwinxp(int on) | ||
2973 | { | ||
2974 | static smallint is_winxp; | ||
2975 | struct var **vpp; | ||
2976 | struct var *vp; | ||
2977 | |||
2978 | if (++on == is_winxp) | ||
2979 | return; | ||
2980 | is_winxp = on; | ||
2981 | |||
2982 | for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) { | ||
2983 | for (vp = *vpp; vp; vp = vp->next) { | ||
2984 | if ((vp->flags & VIMPORT)) { | ||
2985 | char *end = strchr(vp->var_text, '='); | ||
2986 | if (!end || is_prefixed_with(vp->var_text, "COMSPEC=") || | ||
2987 | is_prefixed_with(vp->var_text, "SYSTEMROOT=")) | ||
2988 | continue; | ||
2989 | if (!winxp) | ||
2990 | bs_to_slash(end + 1); | ||
2991 | else | ||
2992 | slash_to_bs(end + 1); | ||
2993 | } | ||
2994 | } | ||
2995 | } | ||
2996 | } | ||
2997 | #endif | ||
2998 | |||
2966 | 2999 | ||
2967 | /* ============ Path search helper */ | 3000 | /* ============ Path search helper */ |
2968 | static const char * | 3001 | static const char * |
@@ -10841,6 +10874,9 @@ optschanged(void) | |||
10841 | #if ENABLE_ASH_NOCONSOLE | 10874 | #if ENABLE_ASH_NOCONSOLE |
10842 | hide_console(noconsole); | 10875 | hide_console(noconsole); |
10843 | #endif | 10876 | #endif |
10877 | #if ENABLE_PLATFORM_MINGW32 | ||
10878 | setwinxp(winxp); | ||
10879 | #endif | ||
10844 | } | 10880 | } |
10845 | 10881 | ||
10846 | struct localvar_list { | 10882 | struct localvar_list { |
@@ -15768,7 +15804,9 @@ static void setvar_if_unset(const char *key, const char *value) | |||
15768 | static NOINLINE void | 15804 | static NOINLINE void |
15769 | init(void) | 15805 | init(void) |
15770 | { | 15806 | { |
15771 | #if !ENABLE_PLATFORM_MINGW32 | 15807 | #if ENABLE_PLATFORM_MINGW32 |
15808 | int import = 0; | ||
15809 | #else | ||
15772 | /* we will never free this */ | 15810 | /* we will never free this */ |
15773 | basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ); | 15811 | basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ); |
15774 | basepf.linno = 1; | 15812 | basepf.linno = 1; |
@@ -15810,6 +15848,7 @@ init(void) | |||
15810 | char *start, *end; | 15848 | char *start, *end; |
15811 | struct passwd *pw; | 15849 | struct passwd *pw; |
15812 | 15850 | ||
15851 | import = VIMPORT; | ||
15813 | for (envp = environ; envp && *envp; envp++) { | 15852 | for (envp = environ; envp && *envp; envp++) { |
15814 | if (!(end=strchr(*envp, '='))) | 15853 | if (!(end=strchr(*envp, '='))) |
15815 | continue; | 15854 | continue; |
@@ -15831,14 +15870,6 @@ init(void) | |||
15831 | /* make all variable names uppercase */ | 15870 | /* make all variable names uppercase */ |
15832 | for (start = *envp;start < end;start++) | 15871 | for (start = *envp;start < end;start++) |
15833 | *start = toupper(*start); | 15872 | *start = toupper(*start); |
15834 | |||
15835 | /* Convert backslashes to forward slashes in value but | ||
15836 | * not if we're on Windows XP or for variables known to | ||
15837 | * cause problems */ | ||
15838 | if (!winxp && !is_prefixed_with(*envp, "SYSTEMROOT=") && | ||
15839 | !is_prefixed_with(*envp, "COMSPEC=")) { | ||
15840 | bs_to_slash(end+1); | ||
15841 | } | ||
15842 | } | 15873 | } |
15843 | 15874 | ||
15844 | /* Initialise some variables normally set at login, but | 15875 | /* Initialise some variables normally set at login, but |
@@ -15868,7 +15899,7 @@ init(void) | |||
15868 | #if !ENABLE_PLATFORM_MINGW32 | 15899 | #if !ENABLE_PLATFORM_MINGW32 |
15869 | setvareq(*envp, VEXPORT|VTEXTFIXED); | 15900 | setvareq(*envp, VEXPORT|VTEXTFIXED); |
15870 | #else | 15901 | #else |
15871 | setvareq(*envp, VEXPORT); | 15902 | setvareq(*envp, VEXPORT|import); |
15872 | #endif | 15903 | #endif |
15873 | } | 15904 | } |
15874 | } | 15905 | } |
@@ -16101,9 +16132,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
16101 | exception_handler = &jmploc; | 16132 | exception_handler = &jmploc; |
16102 | rootpid = getpid(); | 16133 | rootpid = getpid(); |
16103 | 16134 | ||
16104 | #if ENABLE_PLATFORM_MINGW32 | ||
16105 | winxp = (argv[1] != NULL && strcmp(argv[1], "-X") == 0); | ||
16106 | #endif | ||
16107 | init(); | 16135 | init(); |
16108 | setstackmark(&smark); | 16136 | setstackmark(&smark); |
16109 | 16137 | ||