From 723190cf7131e1655aab478bd4d15d75516df496 Mon Sep 17 00:00:00 2001
From: Christopher Faylor <me@cgf.cx>
Date: Fri, 11 May 2001 03:27:22 +0000
Subject: [PATCH] Christopher Faylor <cgf@redhat.com> * environ.cc (winenv):
 Always add SYSTEMDRIVE and SYSYEMROOT to win32-style environment if they
 don't already exist.

---
 winsup/cygwin/ChangeLog  |  6 +++++
 winsup/cygwin/environ.cc | 52 +++++++++++++++++++++++++++++++++-------
 2 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c278a9188..5fb17fa7b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,9 @@
+2001-05-10  Egor Duda  <deo@logos-m.ru>
+	    Christopher Faylor <cgf@redhat.com>
+
+	* environ.cc (winenv): Always add SYSTEMDRIVE and SYSYEMROOT to
+	win32-style environment if they don't already exist.
+
 2001-05-10  Kazuhiro Fujieda  <fujieda@jaist.ac.jp>
         
 	* path.cc (mount_info::conv_to_win32_path): Treat UNC paths the same as
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index d542d73c1..793cebb65 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -728,6 +728,16 @@ env_sort (const void *a, const void *b)
   return strcmp (*p, *q);
 }
 
+/* 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.
    Converts environment variables noted in conv_envvars into win32 form
@@ -737,38 +747,62 @@ winenv (const char * const *envp, int keep_posix)
 {
   int len, n, tl;
   const char * const *srcp;
-  const char * *dstp;
+  const char **dstp;
+  bool saw_forced_winenv[FORCED_WINENV_SIZE] = {0};
+  char *p;
+
+  debug_printf ("envp %p, keep_posix %d", envp, keep_posix);
+
+  tl = 0;
 
   for (n = 0; envp[n]; n++)
     continue;
 
-  const char *newenvp[n + 1];
+  const char *newenvp[n + 1 + FORCED_WINENV_SIZE];
 
-  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;
+      len = strcspn (*srcp, "=");
       win_env *conv;
 
-      if (keep_posix || !(conv = getwinenv (*srcp, *srcp + len)))
+      if (keep_posix || !(conv = getwinenv (*srcp, *srcp + len + 1)))
 	*dstp = *srcp;
       else
 	{
-	  char *p = (char *) alloca (strlen (conv->native) + 1);
+	  p = (char *) alloca (strlen (conv->native) + 1);
 	  strcpy (p, conv->native);
 	  *dstp = p;
 	}
       tl += strlen (*dstp) + 1;
       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 = '=';
 	  *dstp = p;
 	}
+
+      for (int i = 0; forced_winenv_vars[i]; i++)
+	if (!saw_forced_winenv[i])
+	  saw_forced_winenv[i] = strncasematch (forced_winenv_vars[i], *srcp, len);
     }
 
+  for (int i = 0; forced_winenv_vars[i]; i++)
+    if (!saw_forced_winenv[i])
+      {
+	len = strlen (forced_winenv_vars[i]);
+	p = (char *) alloca (len + MAX_PATH + 1);
+	strcpy (p, forced_winenv_vars[i]);
+	strcat (p, "=");
+	if (!GetEnvironmentVariable (forced_winenv_vars[i], p + len + 1, MAX_PATH))
+	  debug_printf ("warning: %s not present in environment", *srcp);
+	else
+	  {
+	    *dstp++ = p;
+	    tl += strlen (p) + 1;
+	  }
+      }
+
   *dstp = NULL;		/* Terminate */
 
   int envlen = dstp - newenvp;