Index: environ.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/environ.cc,v retrieving revision 1.49 diff -u -p -2 -r1.49 environ.cc --- environ.cc 2001/05/04 20:39:38 1.49 +++ environ.cc 2001/05/10 09:13:02 @@ -729,4 +729,22 @@ env_sort (const void *a, const void *b) } +static char* +append_to_winenv (char* winenvp, const char* str) +{ + int len = strlen (str); + memcpy (winenvp, str, len + 1); + return (winenvp + len + 1); +} + +/* Keep this list in upper case and sorted */ +const char* forced_winenv_vars [] = + { + "SYSTEMDRIVE", + "SYSTEMROOT", + NULL + }; + +#define FORCED_WINENV_SIZE (sizeof (forced_winenv_vars) / sizeof (forced_winenv_vars[0])) + /* Create a Windows-style environment block, i.e. a typical character buffer filled with null terminated strings, terminated by double null characters. @@ -736,8 +754,17 @@ char * __stdcall winenv (const char * const *envp, int keep_posix) { - int len, n, tl; + int len, n, tl, cmp; const char * const *srcp; + const char * const *forced_srcp; + const char *native_srcp; const char * *dstp; + const char* native_env_ptr [FORCED_WINENV_SIZE]; + const char* const *cygwin_env_ptr [FORCED_WINENV_SIZE]; + char* p; + debug_printf ("envp %p, keep_posix %d", envp, keep_posix); + + tl = 0; + for (n = 0; envp[n]; n++) continue; @@ -745,7 +772,5 @@ winenv (const char * const *envp, int ke const char *newenvp[n + 1]; - debug_printf ("envp %p, keep_posix %d", envp, keep_posix); - - for (tl = 0, srcp = envp, dstp = newenvp; *srcp; srcp++, dstp++) + for (srcp = envp, dstp = newenvp; *srcp; srcp++, dstp++) { len = strcspn (*srcp, "=") + 1; @@ -756,5 +781,5 @@ winenv (const char * const *envp, int ke else { - char *p = (char *) alloca (strlen (conv->native) + 1); + p = (char *) alloca (strlen (conv->native) + 1); strcpy (p, conv->native); *dstp = p; @@ -763,5 +788,5 @@ winenv (const char * const *envp, int ke if ((*dstp)[0] == '!' && isdrive ((*dstp) + 1) && (*dstp)[3] == '=') { - char *p = (char *) alloca (strlen (*dstp) + 1); + p = (char *) alloca (strlen (*dstp) + 1); strcpy (p, *dstp); *p = '='; @@ -778,13 +803,61 @@ winenv (const char * const *envp, int ke qsort (newenvp, envlen, sizeof (char *), env_sort); + for (srcp = newenvp, forced_srcp = forced_winenv_vars, n = 0, len = strlen (*forced_srcp); + *srcp || *forced_srcp; ) + { + if (*srcp == 0) + cmp = -1; + else if (*forced_srcp == 0) + cmp = 1; + else + cmp = strncmp (*forced_srcp, *srcp, len); + if (cmp < 0) + { + /* forced variable not presen in envp. scan native environent for + its value, and remember pointer for later inclusion */ + for (native_srcp = GetEnvironmentStrings (); + *native_srcp && + ! strncasematch (*forced_srcp, native_srcp, len); + native_srcp += strlen (native_srcp) + 1) + /* do nothing */ ; + if (*native_srcp) + { + native_env_ptr [n] = native_srcp; + tl += strlen (native_srcp) + 1; + } + else + native_env_ptr [n] = 0; + + cygwin_env_ptr [n] = srcp; + n++; + forced_srcp++; + if (*forced_srcp) + len = strlen (*forced_srcp); + } + else if (cmp > 0) + srcp++; + else + { + srcp++; + forced_srcp++; + if (*forced_srcp) + len = strlen (*forced_srcp); + } + } + cygwin_env_ptr [n] = 0; + /* Create an environment block suitable for passing to CreateProcess. */ char *ptr, *envblock; envblock = (char *) malloc (tl + 2); - for (srcp = newenvp, ptr = envblock; *srcp; srcp++) + for (n = 0, srcp = newenvp, ptr = envblock; *srcp; srcp++) { - len = strlen (*srcp); - memcpy (ptr, *srcp, len + 1); - ptr += len + 1; + for (; cygwin_env_ptr [n] == srcp; n++) + { + if (native_env_ptr [n] && *(native_env_ptr [n])) + ptr = append_to_winenv (ptr, native_env_ptr [n]); + } + ptr = append_to_winenv (ptr, *srcp); } + *ptr = '\0'; /* Two null bytes at the end */