+ /* 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;
+ }
+