diff src/process-nt.c @ 355:182f72e8cd0d r21-1-7

Import from CVS: tag r21-1-7
author cvs
date Mon, 13 Aug 2007 10:56:21 +0200
parents 4f79e16b1112
children 8e84bee8ddd0
line wrap: on
line diff
--- a/src/process-nt.c	Mon Aug 13 10:55:35 2007 +0200
+++ b/src/process-nt.c	Mon Aug 13 10:56:21 2007 +0200
@@ -403,8 +403,6 @@
  * must signal an error instead.
  */
 
-/* #### This function completely ignores Vprocess_environment */
-
 static void
 signal_cannot_launch (Lisp_Object image_file, DWORD err)
 {
@@ -420,6 +418,7 @@
   HANDLE hmyshove, hmyslurp, hprocin, hprocout;
   LPTSTR command_line;
   BOOL do_io, windowed;
+  char *proc_env;
 
   /* Find out whether the application is windowed or not */
   {
@@ -507,6 +506,80 @@
     UNGCPRO; /* args_or_ret */
   }
 
+  /* Set `proc_env' to a nul-separated array of the strings in
+     Vprocess_environment terminated by 2 nuls.  */
+ 
+  {
+    extern int compare_env (const char **strp1, const char **strp2);
+    char **env;
+    REGISTER Lisp_Object tem;
+    REGISTER char **new_env;
+    REGISTER int new_length = 0, i, new_space;
+    char *penv;
+    
+    for (tem = Vprocess_environment;
+ 	 (CONSP (tem)
+ 	  && STRINGP (XCAR (tem)));
+ 	 tem = XCDR (tem))
+      new_length++;
+    
+    /* new_length + 1 to include terminating 0.  */
+    env = new_env = alloca_array (char *, new_length + 1);
+ 
+    /* Copy the Vprocess_environment strings into new_env.  */
+    for (tem = Vprocess_environment;
+ 	 (CONSP (tem)
+ 	  && STRINGP (XCAR (tem)));
+ 	 tem = XCDR (tem))
+      {
+	char **ep = env;
+	char *string = (char *) XSTRING_DATA (XCAR (tem));
+	/* See if this string duplicates any string already in the env.
+	   If so, don't put it in.
+	   When an env var has multiple definitions,
+	   we keep the definition that comes first in process-environment.  */
+	for (; ep != new_env; ep++)
+	  {
+	    char *p = *ep, *q = string;
+	    while (1)
+	      {
+		if (*q == 0)
+		  /* The string is malformed; might as well drop it.  */
+		  goto duplicate;
+		if (*q != *p)
+		  break;
+		if (*q == '=')
+		  goto duplicate;
+		p++, q++;
+	      }
+	  }
+	*new_env++ = string;
+      duplicate: ;
+      }
+    *new_env = 0;
+    
+    /* Sort the environment variables */
+    new_length = new_env - env;
+    qsort (env, new_length, sizeof (char *), compare_env);
+    
+    /* Work out how much space to allocate */
+    new_space = 0;
+    for (i = 0; i < new_length; i++)
+      {
+ 	new_space += strlen(env[i]) + 1;
+      }
+    new_space++;
+    
+    /* Allocate space and copy variables into it */
+    penv = proc_env = alloca(new_space);
+    for (i = 0; i < new_length; i++)
+      {
+ 	strcpy(penv, env[i]);
+ 	penv += strlen(env[i]) + 1;
+      }
+    *penv = 0;
+  }
+  
   /* Create process */
   {
     STARTUPINFO si;
@@ -527,7 +600,7 @@
     err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE,
 			  CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP
 			  | CREATE_SUSPENDED,
-			  NULL, (char *) XSTRING_DATA (cur_dir), &si, &pi)
+			  proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi)
 	   ? 0 : GetLastError ());
 
     if (do_io)