Because WINENV is limited (32767 bytes), and HOSTENV can be much larger, a whitelisting approach is used to keep WINENV as small as possible. Currently, only the following envvars are propagated from the host env to WINENV WINEPATH, WINEPWD, WINEHOME, WINETEMP, WINETMP, WINEQT_, WINEVK_, WINEXDG_SESSION_TYPE
Moreover, the NIXENV (env for running wine processes - not applications) on the host system is not produced from WINENV anymore, but the global ENV is propagated to all wine processes and threads.
This might be an alternative approach to MR!5231, MR!6140, bug #56941 and should provide a more deterministic behaviour of wine, because unrelated envvars do have no influence on the env for running windows applications.
Initial tests (winemine, notepad, cmd, etc) seem to run fine, but some envvars might need additional consideration. XVDK_* was mentioned, WINE*, MESA_*, VK_*, QT_*, LIBGL_* are other suspects.
Moreover, this is my first merge request, so your feedback is highly appreciated.
-- v20: ntdll: main_envp has been replaced by environ ntdll: remove is_dynamic_env_var(...) because it is not needed anymore ntdll: remove unused vars ntdll: remove dead code ntdll: conversion from HOSTENV to WINENV is now using whitelisting instead of blacklisting of envvars currently only envvars "WINE"<special_var> (as defined in is_special_env_var() ) are whitelisted. ntdll: separate env for windows applications (WINENV) from env for wine processes (NIXENV) WINENV is typically limited to 32767 WCHAR, the host environment where wine processes are running can be much larger. Keeping the two envs separate enables a more granula handling of envvars. (see also MR!5231, MR!6140, bug #56941)
From: Alois SCHLOEGL alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index f95bf737f56..4a705d73e24 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -488,6 +488,8 @@ const char *ntdll_get_data_dir(void) * build_envp * * Build the environment of a new child process. + * converts WINENV (WCHAR*) to NIXENV (char*) + * Use HOSTENV stored in global var main_envp */ char **build_envp( const WCHAR *envW ) { @@ -497,6 +499,12 @@ char **build_envp( const WCHAR *envW ) int count = 1, length, lenW; unsigned int i;
+#if 1 + /* to not convert from WINENV but use HOSTENV */ + return main_envp; +#else + + /* convert WINENV to NIXENV */ lenW = get_env_length( envW ); if (!(env = malloc( lenW * 3 ))) return NULL; length = ntdll_wcstoumbs( envW, lenW, env, lenW * 3, FALSE ); @@ -549,6 +557,7 @@ char **build_envp( const WCHAR *envW ) } free( env ); return envp; +#endif }
From: Alois SCHLOEGL alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 4a705d73e24..ed3f449be46 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -935,6 +935,13 @@ static const char overrides_help_message[] = * get_initial_environment * * Return the initial environment. + * converts HOSTENV (char*) to WINENV (WCHAR*) + * HOSTENV is stored in global var main_envp + * WINENV is returned in *env. + * pos: returns size [in WCHAR] of win environment + * size: returns size [in bytes] of host environment + * return value is host env converted to win env + with special and dynamic envvars beeing ignored */ static WCHAR *get_initial_environment( SIZE_T *pos, SIZE_T *size ) { @@ -964,6 +971,12 @@ static WCHAR *get_initial_environment( SIZE_T *pos, SIZE_T *size ) } else if (is_special_env_var( str )) continue; /* skip it */
+#if 1 + // do whitelisting instead of blacklisting of envvars + // prevents propagating nixenv to winenv, except "WINE"+special-env-var + else continue; +#endif + if (is_dynamic_env_var( str )) continue; ptr += ntdll_umbstowcs( str, strlen(str) + 1, ptr, end - ptr ); }
From: Alois Schlögl alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 72 +++---------------------------------------- 1 file changed, 4 insertions(+), 68 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index ed3f449be46..9c456409c88 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -499,65 +499,8 @@ char **build_envp( const WCHAR *envW ) int count = 1, length, lenW; unsigned int i;
-#if 1 /* to not convert from WINENV but use HOSTENV */ return main_envp; -#else - - /* convert WINENV to NIXENV */ - lenW = get_env_length( envW ); - if (!(env = malloc( lenW * 3 ))) return NULL; - length = ntdll_wcstoumbs( envW, lenW, env, lenW * 3, FALSE ); - - for (p = env; *p; p += strlen(p) + 1, count++) - { - if (is_dynamic_env_var( p )) continue; - if (is_special_env_var( p )) length += 4; /* prefix it with "WINE" */ - } - - for (i = 0; i < ARRAY_SIZE( unix_vars ); i++) - { - if (!(p = getenv(unix_vars[i]))) continue; - length += strlen(unix_vars[i]) + strlen(p) + 2; - count++; - } - - if ((envp = malloc( count * sizeof(*envp) + length ))) - { - char **envptr = envp; - char *dst = (char *)(envp + count); - - /* some variables must not be modified, so we get them directly from the unix env */ - for (i = 0; i < ARRAY_SIZE( unix_vars ); i++) - { - if (!(p = getenv( unix_vars[i] ))) continue; - *envptr++ = strcpy( dst, unix_vars[i] ); - strcat( dst, "=" ); - strcat( dst, p ); - dst += strlen(dst) + 1; - } - - /* now put the Windows environment strings */ - for (p = env; *p; p += strlen(p) + 1) - { - if (*p == '=') continue; /* skip drive curdirs, this crashes some unix apps */ - if (is_dynamic_env_var( p )) continue; - if (is_special_env_var( p )) /* prefix it with "WINE" */ - { - *envptr++ = strcpy( dst, "WINE" ); - strcat( dst, p ); - } - else - { - *envptr++ = strcpy( dst, p ); - } - dst += strlen(dst) + 1; - } - *envptr = 0; - } - free( env ); - return envp; -#endif }
@@ -962,23 +905,16 @@ static WCHAR *get_initial_environment( SIZE_T *pos, SIZE_T *size ) /* skip Unix special variables and use the Wine variants instead */ if (!strncmp( str, "WINE", 4 )) { - if (is_special_env_var( str + 4 )) str += 4; + if (is_special_env_var( str + 4 )) { + str += 4; + ptr += ntdll_umbstowcs( str, strlen(str) + 1, ptr, end - ptr ); + } else if (!strcmp( str, "WINEDLLOVERRIDES=help" )) { MESSAGE( overrides_help_message ); exit(0); } } - else if (is_special_env_var( str )) continue; /* skip it */ - -#if 1 - // do whitelisting instead of blacklisting of envvars - // prevents propagating nixenv to winenv, except "WINE"+special-env-var - else continue; -#endif - - if (is_dynamic_env_var( str )) continue; - ptr += ntdll_umbstowcs( str, strlen(str) + 1, ptr, end - ptr ); } *pos = ptr - env; return env;
From: Alois Schlögl alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 9c456409c88..a8b5e41de63 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -493,12 +493,6 @@ const char *ntdll_get_data_dir(void) */ char **build_envp( const WCHAR *envW ) { - static const char * const unix_vars[] = { "PATH", "TEMP", "TMP", "HOME" }; - char **envp; - char *env, *p; - int count = 1, length, lenW; - unsigned int i; - /* to not convert from WINENV but use HOSTENV */ return main_envp; }
From: Alois Schlögl alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 18 ------------------ 1 file changed, 18 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index a8b5e41de63..3e450b03234 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -348,24 +348,6 @@ static BOOL is_special_env_var( const char *var ) STARTS_WITH( var, "XDG_SESSION_TYPE=" )); }
-/* check if an environment variable changes dynamically in every new process */ -static BOOL is_dynamic_env_var( const char *var ) -{ - return (STARTS_WITH( var, "WINEDLLOVERRIDES=" ) || - STARTS_WITH( var, "WINEDATADIR=" ) || - STARTS_WITH( var, "WINEHOMEDIR=" ) || - STARTS_WITH( var, "WINEBUILDDIR=" ) || - STARTS_WITH( var, "WINECONFIGDIR=" ) || - STARTS_WITH( var, "WINELOADER=" ) || - STARTS_WITH( var, "WINEDLLDIR" ) || - STARTS_WITH( var, "WINEUNIXCP=" ) || - STARTS_WITH( var, "WINEUSERLOCALE=" ) || - STARTS_WITH( var, "WINEUSERNAME=" ) || - STARTS_WITH( var, "WINEPRELOADRESERVE=" ) || - STARTS_WITH( var, "WINELOADERNOEXEC=" ) || - STARTS_WITH( var, "WINESERVERSOCKET=" )); -} - /****************************************************************** * ntdll_umbstowcs (ntdll.so) *
From: Alois Schlögl alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 3e450b03234..185c60f158b 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -471,12 +471,12 @@ const char *ntdll_get_data_dir(void) * * Build the environment of a new child process. * converts WINENV (WCHAR*) to NIXENV (char*) - * Use HOSTENV stored in global var main_envp + * Use HOSTENV stored in global var environ */ char **build_envp( const WCHAR *envW ) { /* to not convert from WINENV but use HOSTENV */ - return main_envp; + return environ; }
@@ -855,7 +855,7 @@ static const char overrides_help_message[] = * * Return the initial environment. * converts HOSTENV (char*) to WINENV (WCHAR*) - * HOSTENV is stored in global var main_envp + * HOSTENV is stored in global var environ * WINENV is returned in *env. * pos: returns size [in WCHAR] of win environment * size: returns size [in bytes] of host environment
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=148079
Your paranoid android.
=== debian11 (build log) ===
error: patch failed: dlls/ntdll/unix/env.c:499 error: patch failed: dlls/ntdll/unix/env.c:493 error: patch failed: dlls/ntdll/unix/env.c:348 error: patch failed: dlls/ntdll/unix/env.c:471 Task: Patch failed to apply
=== debian11b (build log) ===
error: patch failed: dlls/ntdll/unix/env.c:499 error: patch failed: dlls/ntdll/unix/env.c:493 error: patch failed: dlls/ntdll/unix/env.c:348 error: patch failed: dlls/ntdll/unix/env.c:471 Task: Patch failed to apply