+ int env_size;
+
+ /* Count the number of environment bindings supplied. */
+ for (env_size = 0; env[env_size]; env_size++)
+ continue;
+
+ /* Assemble an environment block, if required. This consists of
+ VAR=VALUE strings juxtaposed (with one null character between each
+ pair) and an additional null at the end. */
+ if (env_size > 0)
+ {
+ int var;
+ int total_size = 1; /* 1 is for the final null. */
+ char *bufptr;
+
+ /* Windows needs the members of the block to be sorted by variable
+ name. */
+ env_copy = (char **) alloca (sizeof (char *) * env_size);
+ memcpy (env_copy, env, sizeof (char *) * env_size);
+ qsort (env_copy, env_size, sizeof (char *), env_compare);
+
+ for (var = 0; var < env_size; var++)
+ total_size += strlen (env[var]) + 1;
+
+ env_block = XNEWVEC (char, total_size);
+ bufptr = env_block;
+ for (var = 0; var < env_size; var++)
+ bufptr = stpcpy (bufptr, env_copy[var]) + 1;
+
+ *bufptr = '\0';
+ }
+ }
+
+ full_executable = find_executable (executable, search);
+ if (!full_executable)
+ goto error;
+ cmdline = argv_to_cmdline (argv);
+ if (!cmdline)
+ goto error;
+
+ /* Create the child process. */
+ if (!CreateProcess (full_executable, cmdline,
+ /*lpProcessAttributes=*/NULL,
+ /*lpThreadAttributes=*/NULL,
+ /*bInheritHandles=*/TRUE,
+ dwCreationFlags,
+ (LPVOID) env_block,
+ /*lpCurrentDirectory=*/NULL,
+ si,
+ pi))
+ {
+ free (env_block);
+
+ free (full_executable);
+
+ return (pid_t) -1;
+ }
+
+ /* Clean up. */
+ CloseHandle (pi->hThread);
+ free (full_executable);
+ free (env_block);
+
+ return (pid_t) pi->hProcess;
+
+ error:
+ free (env_block);
+ free (cmdline);
+ free (full_executable);
+
+ return (pid_t) -1;
+}
+
+/* Spawn a script. This simulates the Unix script execution mechanism.
+ This function is called as a fallback if win32_spawn fails. */
+
+static pid_t
+spawn_script (const char *executable, char *const *argv,
+ char* const *env,
+ DWORD dwCreationFlags,
+ LPSTARTUPINFO si,
+ LPPROCESS_INFORMATION pi)
+{
+ pid_t pid = (pid_t) -1;
+ int save_errno = errno;
+ int fd = _open (executable, _O_RDONLY);
+
+ /* Try to open script, check header format, extract interpreter path,
+ and spawn script using that interpretter. */
+ if (fd >= 0)
+ {
+ char buf[MAX_PATH + 5];
+ int len = _read (fd, buf, sizeof (buf) - 1);
+ _close (fd);
+ if (len > 3)