int, int, int, int,
const char **, int *);
static int pex_win32_close (struct pex_obj *, int);
-static int pex_win32_wait (struct pex_obj *, pid_t, int *,
+static pid_t pex_win32_wait (struct pex_obj *, pid_t, int *,
struct pex_time *, int, const char **, int *);
static int pex_win32_pipe (struct pex_obj *, int *, int);
static FILE *pex_win32_fdopenr (struct pex_obj *, int, int);
if (!namebuf || !foundbuf)
{
RegCloseKey (hKey);
- if (namebuf)
- free (namebuf);
- if (foundbuf)
- free (foundbuf);
+ free (namebuf);
+ free (foundbuf);
return executable;
}
return tack_on_executable (buf, executable);
/* failed */
- if (buf)
- free (buf);
+ free (buf);
return executable;
}
#endif
si,
pi))
{
- if (env_block)
- free (env_block);
+ free (env_block);
free (full_executable);
/* Clean up. */
CloseHandle (pi->hThread);
free (full_executable);
- if (env_block)
- free (env_block);
+ free (env_block);
return (pid_t) pi->hProcess;
error:
- if (env_block)
- free (env_block);
- if (cmdline)
- free (cmdline);
- if (full_executable)
- free (full_executable);
+ free (env_block);
+ free (cmdline);
+ free (full_executable);
return (pid_t) -1;
}
dwCreationFlags, si, pi);
if (executable1 != newex)
free ((char *) newex);
- if ((long) pid < 0)
+ if (pid == (pid_t) -1)
{
newex = msys_rootify (executable1);
if (newex != executable1)
}
}
}
- if ((long) pid < 0)
+ if (pid == (pid_t) -1)
errno = save_errno;
return pid;
}
OSVERSIONINFO version_info;
STARTUPINFO si;
PROCESS_INFORMATION pi;
+ int orig_out, orig_in, orig_err;
+ BOOL separate_stderr = !(flags & PEX_STDERR_TO_STDOUT);
+
+ /* Ensure we have inheritable descriptors to pass to the child. */
+ orig_in = in;
+ in = _dup (orig_in);
+
+ orig_out = out;
+ out = _dup (orig_out);
+
+ if (separate_stderr)
+ {
+ orig_err = errdes;
+ errdes = _dup (orig_err);
+ }
stdin_handle = INVALID_HANDLE_VALUE;
stdout_handle = INVALID_HANDLE_VALUE;
stdin_handle = (HANDLE) _get_osfhandle (in);
stdout_handle = (HANDLE) _get_osfhandle (out);
- if (!(flags & PEX_STDERR_TO_STDOUT))
+ if (separate_stderr)
stderr_handle = (HANDLE) _get_osfhandle (errdes);
else
stderr_handle = stdout_handle;
*errmsg = "CreateProcess";
}
- /* Close the standard output and standard error handles in the
- parent. */
- if (out != STDOUT_FILENO)
- obj->funcs->close (obj, out);
- if (errdes != STDERR_FILENO)
- obj->funcs->close (obj, errdes);
+ /* If the child was created successfully, close the original file
+ descriptors. If the process creation fails, these are closed by
+ pex_run_in_environment instead. We must not close them twice as
+ that seems to cause a Windows exception. */
+
+ if (pid != (pid_t) -1)
+ {
+ if (orig_in != STDIN_FILENO)
+ _close (orig_in);
+ if (orig_out != STDOUT_FILENO)
+ _close (orig_out);
+ if (separate_stderr
+ && orig_err != STDERR_FILENO)
+ _close (orig_err);
+ }
+
+ /* Close the standard input, standard output and standard error handles
+ in the parent. */
+
+ _close (in);
+ _close (out);
+ if (separate_stderr)
+ _close (errdes);
return pid;
}
status == 3. We fix the status code to conform to the usual WIF*
macros. Note that WIFSIGNALED will never be true under CRTDLL. */
-static int
+static pid_t
pex_win32_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid,
int *status, struct pex_time *time, int done ATTRIBUTE_UNUSED,
const char **errmsg, int *err)
pex_win32_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
int binary)
{
- return _pipe (p, 256, binary ? _O_BINARY : _O_TEXT);
+ return _pipe (p, 256, (binary ? _O_BINARY : _O_TEXT) | _O_NOINHERIT);
}
/* Get a FILE pointer to read from a file descriptor. */
pex_win32_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
int binary)
{
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ if (h == INVALID_HANDLE_VALUE)
+ return NULL;
+ if (! SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0))
+ return NULL;
return fdopen (fd, binary ? "rb" : "r");
}