aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-06-21 08:48:57 +0100
committerRon Yorston <rmy@pobox.com>2023-06-21 08:48:57 +0100
commit3e73f1bd10d208a6a5636fdae632a58e892ad42a (patch)
tree7ca372b7d163fb0ae47d2bf89b5b8b9ff377c06c
parent29f13acfb2d3818592d93590aa06de3c4f169b42 (diff)
downloadbusybox-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.c54
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 */
2971static void
2972setwinxp(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 */
2968static const char * 3001static 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
10846struct localvar_list { 10882struct localvar_list {
@@ -15768,7 +15804,9 @@ static void setvar_if_unset(const char *key, const char *value)
15768static NOINLINE void 15804static NOINLINE void
15769init(void) 15805init(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