summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoff Voelker <voelker@cs.washington.edu>1997-01-04 22:26:26 +0000
committerGeoff Voelker <voelker@cs.washington.edu>1997-01-04 22:26:26 +0000
commit480d707337713a4db5c81050a6f2cbb80483b82f (patch)
treed7e144d1629e4be92931682312a9de2ba167ac5d
parent347dfc36da34482cea1f7eb38d811e2ab6d19fe7 (diff)
downloademacs-480d707337713a4db5c81050a6f2cbb80483b82f.tar.gz
(compare_env, merge_and_sort_env): New functions.
(sys_spawnve): Sort environment variables for subprocess. (ppid_env_var_buffer): Variable deleted.
-rw-r--r--src/w32proc.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/src/w32proc.c b/src/w32proc.c
index b8ada136cd3..755336299b4 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -577,9 +577,49 @@ w32_is_dos_binary (char * filename)
return is_dos_binary;
}
-/* We pass our process ID to our children by setting up an environment
- variable in their environment. */
-char ppid_env_var_buffer[64];
+int
+compare_env (const char **strp1, const char **strp2)
+{
+ const char *str1 = *strp1, *str2 = *strp2;
+
+ while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
+ {
+ if (tolower (*str1) > tolower (*str2))
+ return 1;
+ else if (tolower (*str1) < tolower (*str2))
+ return -1;
+ str1++, str2++;
+ }
+
+ if (*str1 == '=' && *str2 == '=')
+ return 0;
+ else if (*str1 == '=')
+ return -1;
+ else
+ return 1;
+}
+
+void
+merge_and_sort_env (char **envp1, char **envp2, char **new_envp)
+{
+ char **optr, **nptr;
+ int num;
+
+ nptr = new_envp;
+ optr = envp1;
+ while (*optr)
+ *nptr++ = *optr++;
+ num = optr - envp1;
+
+ optr = envp2;
+ while (*optr)
+ *nptr++ = *optr++;
+ num += optr - envp2;
+
+ qsort (new_envp, num, sizeof (char *), compare_env);
+
+ *nptr = NULL;
+}
/* When a new child process is created we need to register it in our list,
so intercept spawn requests. */
@@ -588,11 +628,15 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
{
Lisp_Object program, full;
char *cmdline, *env, *parg, **targ;
- int arglen;
+ int arglen, numenv;
int pid;
child_process *cp;
int is_dos_binary;
-
+ /* We pass our process ID to our children by setting up an environment
+ variable in their environment. */
+ char ppid_env_var_buffer[64];
+ char *extra_env[] = {ppid_env_var_buffer, NULL};
+
/* We don't care about the other modes */
if (mode != _P_NOWAIT)
{
@@ -726,16 +770,24 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
/* and envp... */
arglen = 1;
targ = envp;
+ numenv = 1; /* for end null */
while (*targ)
{
arglen += strlen (*targ++) + 1;
+ numenv++;
}
+ /* extra env vars... */
sprintf (ppid_env_var_buffer, "__PARENT_PROCESS_ID=%d",
GetCurrentProcessId ());
arglen += strlen (ppid_env_var_buffer) + 1;
+ numenv++;
+ /* merge env passed in and extra env into one, and sort it. */
+ targ = (char **) alloca (numenv * sizeof (char *));
+ merge_and_sort_env (envp, extra_env, targ);
+
+ /* concatenate env entries. */
env = alloca (arglen);
- targ = envp;
parg = env;
while (*targ)
{
@@ -743,8 +795,6 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
parg += strlen (*targ++);
*parg++ = '\0';
}
- strcpy (parg, ppid_env_var_buffer);
- parg += strlen (ppid_env_var_buffer);
*parg++ = '\0';
*parg = '\0';