mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-11 15:06:14 +01:00
[Win32] Fix the asynchronous g_spawn* to return the process handle of the
2002-11-18 Tor Lillqvist <tml@iki.fi> [Win32] Fix the asynchronous g_spawn* to return the process handle of the started program properly. (Note: not the process id. The spawn*() functions in the C runtime return the created process's handle. There doesn't seem to be any way to get the process id of a child process if you have the handle. But then, the process handle usually is more useful anyway.) * glib/gspawn-win32-helper.c (WinMain): If the spawning of the child process succeeded, and if asynchronous spawn (P_NOWAIT), write the result handle up to the parent process, waiting to read it in do_spawn_with_pipes(). * glib/gspawn-win32.c (do_spawn): Use return value from spawning the helper. If it is -1 the helper wasn't found or couldn't be run for some reason. Otherwise it is the helper's process handle. (g_spawn_async_with_pipes): Pass the child_pid parameter on to do_spawn_with_pipes(). (do_spawn_with_pipes): Take also a child_pid parameter. If do_spawn() returned -1, fail immediately. Otherwise make the handle passed to us by the helper process into a handle valid in this process by calling DuplicateHandle().
This commit is contained in:
parent
1f04f2cce2
commit
0b4bcbe1d9
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
|||||||
|
2002-11-18 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
|
[Win32] Fix the asynchronous g_spawn* to return the process handle
|
||||||
|
of the started program properly. (Note: not the process id. The
|
||||||
|
spawn*() functions in the C runtime return the created process's
|
||||||
|
handle. There doesn't seem to be any way to get the process id of
|
||||||
|
a child process if you have the handle. But then, the process
|
||||||
|
handle usually is more useful anyway.)
|
||||||
|
|
||||||
|
* glib/gspawn-win32-helper.c (WinMain): If the spawning of the
|
||||||
|
child process succeeded, and if asynchronous spawn (P_NOWAIT),
|
||||||
|
write the result handle up to the parent process, waiting to read
|
||||||
|
it in do_spawn_with_pipes().
|
||||||
|
|
||||||
|
* glib/gspawn-win32.c (do_spawn): Use return value from spawning
|
||||||
|
the helper. If it is -1 the helper wasn't found or couldn't be run
|
||||||
|
for some reason. Otherwise it is the helper's process handle.
|
||||||
|
|
||||||
|
(g_spawn_async_with_pipes): Pass the child_pid parameter on to
|
||||||
|
do_spawn_with_pipes().
|
||||||
|
|
||||||
|
(do_spawn_with_pipes): Take also a child_pid parameter. If
|
||||||
|
do_spawn() returned -1, fail immediately. Otherwise make the
|
||||||
|
handle passed to us by the helper process into a handle valid in
|
||||||
|
this process by calling DuplicateHandle().
|
||||||
|
|
||||||
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
||||||
|
@ -1,3 +1,29 @@
|
|||||||
|
2002-11-18 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
|
[Win32] Fix the asynchronous g_spawn* to return the process handle
|
||||||
|
of the started program properly. (Note: not the process id. The
|
||||||
|
spawn*() functions in the C runtime return the created process's
|
||||||
|
handle. There doesn't seem to be any way to get the process id of
|
||||||
|
a child process if you have the handle. But then, the process
|
||||||
|
handle usually is more useful anyway.)
|
||||||
|
|
||||||
|
* glib/gspawn-win32-helper.c (WinMain): If the spawning of the
|
||||||
|
child process succeeded, and if asynchronous spawn (P_NOWAIT),
|
||||||
|
write the result handle up to the parent process, waiting to read
|
||||||
|
it in do_spawn_with_pipes().
|
||||||
|
|
||||||
|
* glib/gspawn-win32.c (do_spawn): Use return value from spawning
|
||||||
|
the helper. If it is -1 the helper wasn't found or couldn't be run
|
||||||
|
for some reason. Otherwise it is the helper's process handle.
|
||||||
|
|
||||||
|
(g_spawn_async_with_pipes): Pass the child_pid parameter on to
|
||||||
|
do_spawn_with_pipes().
|
||||||
|
|
||||||
|
(do_spawn_with_pipes): Take also a child_pid parameter. If
|
||||||
|
do_spawn() returned -1, fail immediately. Otherwise make the
|
||||||
|
handle passed to us by the helper process into a handle valid in
|
||||||
|
this process by calling DuplicateHandle().
|
||||||
|
|
||||||
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
||||||
|
@ -1,3 +1,29 @@
|
|||||||
|
2002-11-18 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
|
[Win32] Fix the asynchronous g_spawn* to return the process handle
|
||||||
|
of the started program properly. (Note: not the process id. The
|
||||||
|
spawn*() functions in the C runtime return the created process's
|
||||||
|
handle. There doesn't seem to be any way to get the process id of
|
||||||
|
a child process if you have the handle. But then, the process
|
||||||
|
handle usually is more useful anyway.)
|
||||||
|
|
||||||
|
* glib/gspawn-win32-helper.c (WinMain): If the spawning of the
|
||||||
|
child process succeeded, and if asynchronous spawn (P_NOWAIT),
|
||||||
|
write the result handle up to the parent process, waiting to read
|
||||||
|
it in do_spawn_with_pipes().
|
||||||
|
|
||||||
|
* glib/gspawn-win32.c (do_spawn): Use return value from spawning
|
||||||
|
the helper. If it is -1 the helper wasn't found or couldn't be run
|
||||||
|
for some reason. Otherwise it is the helper's process handle.
|
||||||
|
|
||||||
|
(g_spawn_async_with_pipes): Pass the child_pid parameter on to
|
||||||
|
do_spawn_with_pipes().
|
||||||
|
|
||||||
|
(do_spawn_with_pipes): Take also a child_pid parameter. If
|
||||||
|
do_spawn() returned -1, fail immediately. Otherwise make the
|
||||||
|
handle passed to us by the helper process into a handle valid in
|
||||||
|
this process by calling DuplicateHandle().
|
||||||
|
|
||||||
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
||||||
|
@ -1,3 +1,29 @@
|
|||||||
|
2002-11-18 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
|
[Win32] Fix the asynchronous g_spawn* to return the process handle
|
||||||
|
of the started program properly. (Note: not the process id. The
|
||||||
|
spawn*() functions in the C runtime return the created process's
|
||||||
|
handle. There doesn't seem to be any way to get the process id of
|
||||||
|
a child process if you have the handle. But then, the process
|
||||||
|
handle usually is more useful anyway.)
|
||||||
|
|
||||||
|
* glib/gspawn-win32-helper.c (WinMain): If the spawning of the
|
||||||
|
child process succeeded, and if asynchronous spawn (P_NOWAIT),
|
||||||
|
write the result handle up to the parent process, waiting to read
|
||||||
|
it in do_spawn_with_pipes().
|
||||||
|
|
||||||
|
* glib/gspawn-win32.c (do_spawn): Use return value from spawning
|
||||||
|
the helper. If it is -1 the helper wasn't found or couldn't be run
|
||||||
|
for some reason. Otherwise it is the helper's process handle.
|
||||||
|
|
||||||
|
(g_spawn_async_with_pipes): Pass the child_pid parameter on to
|
||||||
|
do_spawn_with_pipes().
|
||||||
|
|
||||||
|
(do_spawn_with_pipes): Take also a child_pid parameter. If
|
||||||
|
do_spawn() returned -1, fail immediately. Otherwise make the
|
||||||
|
handle passed to us by the helper process into a handle valid in
|
||||||
|
this process by calling DuplicateHandle().
|
||||||
|
|
||||||
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
||||||
|
@ -1,3 +1,29 @@
|
|||||||
|
2002-11-18 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
|
[Win32] Fix the asynchronous g_spawn* to return the process handle
|
||||||
|
of the started program properly. (Note: not the process id. The
|
||||||
|
spawn*() functions in the C runtime return the created process's
|
||||||
|
handle. There doesn't seem to be any way to get the process id of
|
||||||
|
a child process if you have the handle. But then, the process
|
||||||
|
handle usually is more useful anyway.)
|
||||||
|
|
||||||
|
* glib/gspawn-win32-helper.c (WinMain): If the spawning of the
|
||||||
|
child process succeeded, and if asynchronous spawn (P_NOWAIT),
|
||||||
|
write the result handle up to the parent process, waiting to read
|
||||||
|
it in do_spawn_with_pipes().
|
||||||
|
|
||||||
|
* glib/gspawn-win32.c (do_spawn): Use return value from spawning
|
||||||
|
the helper. If it is -1 the helper wasn't found or couldn't be run
|
||||||
|
for some reason. Otherwise it is the helper's process handle.
|
||||||
|
|
||||||
|
(g_spawn_async_with_pipes): Pass the child_pid parameter on to
|
||||||
|
do_spawn_with_pipes().
|
||||||
|
|
||||||
|
(do_spawn_with_pipes): Take also a child_pid parameter. If
|
||||||
|
do_spawn() returned -1, fail immediately. Otherwise make the
|
||||||
|
handle passed to us by the helper process into a handle valid in
|
||||||
|
this process by calling DuplicateHandle().
|
||||||
|
|
||||||
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
||||||
|
@ -1,3 +1,29 @@
|
|||||||
|
2002-11-18 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
|
[Win32] Fix the asynchronous g_spawn* to return the process handle
|
||||||
|
of the started program properly. (Note: not the process id. The
|
||||||
|
spawn*() functions in the C runtime return the created process's
|
||||||
|
handle. There doesn't seem to be any way to get the process id of
|
||||||
|
a child process if you have the handle. But then, the process
|
||||||
|
handle usually is more useful anyway.)
|
||||||
|
|
||||||
|
* glib/gspawn-win32-helper.c (WinMain): If the spawning of the
|
||||||
|
child process succeeded, and if asynchronous spawn (P_NOWAIT),
|
||||||
|
write the result handle up to the parent process, waiting to read
|
||||||
|
it in do_spawn_with_pipes().
|
||||||
|
|
||||||
|
* glib/gspawn-win32.c (do_spawn): Use return value from spawning
|
||||||
|
the helper. If it is -1 the helper wasn't found or couldn't be run
|
||||||
|
for some reason. Otherwise it is the helper's process handle.
|
||||||
|
|
||||||
|
(g_spawn_async_with_pipes): Pass the child_pid parameter on to
|
||||||
|
do_spawn_with_pipes().
|
||||||
|
|
||||||
|
(do_spawn_with_pipes): Take also a child_pid parameter. If
|
||||||
|
do_spawn() returned -1, fail immediately. Otherwise make the
|
||||||
|
handle passed to us by the helper process into a handle valid in
|
||||||
|
this process by calling DuplicateHandle().
|
||||||
|
|
||||||
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
||||||
|
@ -1,3 +1,29 @@
|
|||||||
|
2002-11-18 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
|
[Win32] Fix the asynchronous g_spawn* to return the process handle
|
||||||
|
of the started program properly. (Note: not the process id. The
|
||||||
|
spawn*() functions in the C runtime return the created process's
|
||||||
|
handle. There doesn't seem to be any way to get the process id of
|
||||||
|
a child process if you have the handle. But then, the process
|
||||||
|
handle usually is more useful anyway.)
|
||||||
|
|
||||||
|
* glib/gspawn-win32-helper.c (WinMain): If the spawning of the
|
||||||
|
child process succeeded, and if asynchronous spawn (P_NOWAIT),
|
||||||
|
write the result handle up to the parent process, waiting to read
|
||||||
|
it in do_spawn_with_pipes().
|
||||||
|
|
||||||
|
* glib/gspawn-win32.c (do_spawn): Use return value from spawning
|
||||||
|
the helper. If it is -1 the helper wasn't found or couldn't be run
|
||||||
|
for some reason. Otherwise it is the helper's process handle.
|
||||||
|
|
||||||
|
(g_spawn_async_with_pipes): Pass the child_pid parameter on to
|
||||||
|
do_spawn_with_pipes().
|
||||||
|
|
||||||
|
(do_spawn_with_pipes): Take also a child_pid parameter. If
|
||||||
|
do_spawn() returned -1, fail immediately. Otherwise make the
|
||||||
|
handle passed to us by the helper process into a handle valid in
|
||||||
|
this process by calling DuplicateHandle().
|
||||||
|
|
||||||
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
2002-11-17 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
|
||||||
|
@ -70,7 +70,9 @@ WinMain (struct HINSTANCE__ *hInstance,
|
|||||||
int i;
|
int i;
|
||||||
int fd;
|
int fd;
|
||||||
int mode;
|
int mode;
|
||||||
gint zero = 0;
|
int handle;
|
||||||
|
int no_error = CHILD_NO_ERROR;
|
||||||
|
int zero = 0;
|
||||||
|
|
||||||
SETUP_DEBUG();
|
SETUP_DEBUG();
|
||||||
|
|
||||||
@ -203,10 +205,12 @@ WinMain (struct HINSTANCE__ *hInstance,
|
|||||||
{
|
{
|
||||||
debugstring = g_string_new ("");
|
debugstring = g_string_new ("");
|
||||||
g_string_append (debugstring,
|
g_string_append (debugstring,
|
||||||
g_strdup_printf ("calling %s on program %s, __argv: ",
|
g_strdup_printf ("calling %s %s mode=%s argv: ",
|
||||||
(__argv[ARG_USE_PATH][0] == 'y' ?
|
(__argv[ARG_USE_PATH][0] == 'y' ?
|
||||||
"spawnvp" : "spawnv"),
|
"spawnvp" : "spawnv"),
|
||||||
__argv[ARG_PROGRAM]));
|
__argv[ARG_PROGRAM],
|
||||||
|
(mode == P_WAIT ?
|
||||||
|
"P_WAIT" : "P_NOWAIT")));
|
||||||
i = ARG_PROGRAM+1;
|
i = ARG_PROGRAM+1;
|
||||||
while (__argv[i])
|
while (__argv[i])
|
||||||
{
|
{
|
||||||
@ -218,16 +222,28 @@ WinMain (struct HINSTANCE__ *hInstance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (__argv[ARG_USE_PATH][0] == 'y')
|
if (__argv[ARG_USE_PATH][0] == 'y')
|
||||||
{
|
handle = spawnvp (mode, __argv[ARG_PROGRAM], __argv+ARG_PROGRAM);
|
||||||
if (spawnvp (mode, __argv[ARG_PROGRAM], __argv+ARG_PROGRAM) < 0)
|
|
||||||
write_err_and_exit (child_err_report_fd, CHILD_SPAWN_FAILED);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
handle = spawnv (mode, __argv[ARG_PROGRAM], __argv+ARG_PROGRAM);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
{
|
{
|
||||||
if (spawnv (mode, __argv[ARG_PROGRAM], __argv+ARG_PROGRAM) < 0)
|
debugstring = g_string_new ("");
|
||||||
write_err_and_exit (child_err_report_fd, CHILD_SPAWN_FAILED);
|
g_string_append (debugstring,
|
||||||
|
g_strdup_printf ("%s returned %#x",
|
||||||
|
(__argv[ARG_USE_PATH][0] == 'y' ?
|
||||||
|
"spawnvp" : "spawnv"),
|
||||||
|
handle));
|
||||||
|
MessageBox (NULL, debugstring->str, "gspawn-win32-helper", 0);
|
||||||
}
|
}
|
||||||
write (child_err_report_fd, &zero, sizeof (zero));
|
|
||||||
|
if (handle < 0)
|
||||||
|
write_err_and_exit (child_err_report_fd, CHILD_SPAWN_FAILED);
|
||||||
|
|
||||||
|
write (child_err_report_fd, &no_error, sizeof (no_error));
|
||||||
|
if (mode == P_NOWAIT)
|
||||||
|
write (child_err_report_fd, &handle, sizeof (handle));
|
||||||
|
else
|
||||||
write (child_err_report_fd, &zero, sizeof (zero));
|
write (child_err_report_fd, &zero, sizeof (zero));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,7 @@ static gboolean do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
gboolean child_inherits_stdin,
|
gboolean child_inherits_stdin,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
|
gint *child_pid,
|
||||||
gint *standard_input,
|
gint *standard_input,
|
||||||
gint *standard_output,
|
gint *standard_output,
|
||||||
gint *standard_error,
|
gint *standard_error,
|
||||||
@ -222,6 +223,7 @@ g_spawn_sync (const gchar *working_directory,
|
|||||||
{
|
{
|
||||||
gint outpipe = -1;
|
gint outpipe = -1;
|
||||||
gint errpipe = -1;
|
gint errpipe = -1;
|
||||||
|
gint pid;
|
||||||
GIOChannel *outchannel = NULL;
|
GIOChannel *outchannel = NULL;
|
||||||
GIOChannel *errchannel = NULL;
|
GIOChannel *errchannel = NULL;
|
||||||
GPollFD outfd, errfd;
|
GPollFD outfd, errfd;
|
||||||
@ -262,6 +264,7 @@ g_spawn_sync (const gchar *working_directory,
|
|||||||
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
||||||
child_setup,
|
child_setup,
|
||||||
user_data,
|
user_data,
|
||||||
|
&pid,
|
||||||
NULL,
|
NULL,
|
||||||
standard_output ? &outpipe : NULL,
|
standard_output ? &outpipe : NULL,
|
||||||
standard_error ? &errpipe : NULL,
|
standard_error ? &errpipe : NULL,
|
||||||
@ -451,6 +454,7 @@ g_spawn_async_with_pipes (const gchar *working_directory,
|
|||||||
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
||||||
child_setup,
|
child_setup,
|
||||||
user_data,
|
user_data,
|
||||||
|
child_pid,
|
||||||
standard_input,
|
standard_input,
|
||||||
standard_output,
|
standard_output,
|
||||||
standard_error,
|
standard_error,
|
||||||
@ -537,6 +541,7 @@ do_spawn (gboolean dont_wait,
|
|||||||
gchar **new_argv;
|
gchar **new_argv;
|
||||||
gchar args[ARG_COUNT][10];
|
gchar args[ARG_COUNT][10];
|
||||||
gint i;
|
gint i;
|
||||||
|
int rc;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
|
|
||||||
SETUP_DEBUG();
|
SETUP_DEBUG();
|
||||||
@ -595,7 +600,7 @@ do_spawn (gboolean dont_wait,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (working_directory && *working_directory)
|
if (working_directory && *working_directory)
|
||||||
new_argv[ARG_WORKING_DIRECTORY] = working_directory;
|
new_argv[ARG_WORKING_DIRECTORY] = g_strdup (working_directory);
|
||||||
else
|
else
|
||||||
new_argv[ARG_WORKING_DIRECTORY] = "-";
|
new_argv[ARG_WORKING_DIRECTORY] = "-";
|
||||||
|
|
||||||
@ -638,11 +643,9 @@ do_spawn (gboolean dont_wait,
|
|||||||
/* Let's hope envp hasn't mucked with PATH so that
|
/* Let's hope envp hasn't mucked with PATH so that
|
||||||
* gspawn-win32-helper.exe isn't found.
|
* gspawn-win32-helper.exe isn't found.
|
||||||
*/
|
*/
|
||||||
spawnvpe (P_NOWAIT, "gspawn-win32-helper", new_argv, envp);
|
rc = spawnvpe (P_NOWAIT, "gspawn-win32-helper", new_argv, envp);
|
||||||
else
|
else
|
||||||
spawnvp (P_NOWAIT, "gspawn-win32-helper", new_argv);
|
rc = spawnvp (P_NOWAIT, "gspawn-win32-helper", new_argv);
|
||||||
|
|
||||||
/* FIXME: What if gspawn-win32-helper.exe isn't found? */
|
|
||||||
|
|
||||||
/* Close the child_err_report_fd and the other process's ends of the
|
/* Close the child_err_report_fd and the other process's ends of the
|
||||||
* pipes in this process, otherwise the reader will never get
|
* pipes in this process, otherwise the reader will never get
|
||||||
@ -656,9 +659,10 @@ do_spawn (gboolean dont_wait,
|
|||||||
if (stderr_fd >= 0)
|
if (stderr_fd >= 0)
|
||||||
close (stderr_fd);
|
close (stderr_fd);
|
||||||
|
|
||||||
|
g_free (new_argv[ARG_WORKING_DIRECTORY]);
|
||||||
g_free (new_argv);
|
g_free (new_argv);
|
||||||
|
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -720,6 +724,7 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
gboolean child_inherits_stdin,
|
gboolean child_inherits_stdin,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
|
gint *child_pid,
|
||||||
gint *standard_input,
|
gint *standard_input,
|
||||||
gint *standard_output,
|
gint *standard_output,
|
||||||
gint *standard_error,
|
gint *standard_error,
|
||||||
@ -730,7 +735,7 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
gint stdout_pipe[2] = { -1, -1 };
|
gint stdout_pipe[2] = { -1, -1 };
|
||||||
gint stderr_pipe[2] = { -1, -1 };
|
gint stderr_pipe[2] = { -1, -1 };
|
||||||
gint child_err_report_pipe[2] = { -1, -1 };
|
gint child_err_report_pipe[2] = { -1, -1 };
|
||||||
gint status;
|
gint helper = -1;
|
||||||
gint buf[2];
|
gint buf[2];
|
||||||
gint n_ints = 0;
|
gint n_ints = 0;
|
||||||
|
|
||||||
@ -746,7 +751,7 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
if (standard_error && !make_pipe (stderr_pipe, error))
|
if (standard_error && !make_pipe (stderr_pipe, error))
|
||||||
goto cleanup_and_fail;
|
goto cleanup_and_fail;
|
||||||
|
|
||||||
status = do_spawn (dont_wait,
|
helper = do_spawn (dont_wait,
|
||||||
child_err_report_pipe[1],
|
child_err_report_pipe[1],
|
||||||
stdin_pipe[0],
|
stdin_pipe[0],
|
||||||
stdout_pipe[1],
|
stdout_pipe[1],
|
||||||
@ -762,18 +767,39 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
child_setup,
|
child_setup,
|
||||||
user_data);
|
user_data);
|
||||||
|
|
||||||
|
/* do_spawn() returns -1 if gspawn-win32-helper couldn't be run */
|
||||||
|
if (helper == -1)
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_SPAWN_ERROR,
|
||||||
|
G_SPAWN_ERROR_FAILED,
|
||||||
|
_("Failed to execute helper program"));
|
||||||
|
goto cleanup_and_fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (!read_ints (child_err_report_pipe[0],
|
if (!read_ints (child_err_report_pipe[0],
|
||||||
buf, 2, &n_ints,
|
buf, 2, &n_ints,
|
||||||
error))
|
error) ||
|
||||||
|
n_ints != 2)
|
||||||
goto cleanup_and_fail;
|
goto cleanup_and_fail;
|
||||||
|
|
||||||
if (n_ints == 2)
|
/* Error code from gspawn-win32-helper. */
|
||||||
{
|
|
||||||
/* Error from the child. */
|
|
||||||
|
|
||||||
switch (buf[0])
|
switch (buf[0])
|
||||||
{
|
{
|
||||||
case CHILD_NO_ERROR:
|
case CHILD_NO_ERROR:
|
||||||
|
if (child_pid && dont_wait)
|
||||||
|
{
|
||||||
|
/* helper is our HANDLE for gspawn-win32-helper. It has
|
||||||
|
* told us the HANDLE of its child. Duplicate that into
|
||||||
|
* a HANDLE valid in this process.
|
||||||
|
*/
|
||||||
|
if (!DuplicateHandle ((HANDLE) helper, (HANDLE) buf[1],
|
||||||
|
GetCurrentProcess (), (LPHANDLE) child_pid,
|
||||||
|
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
|
*child_pid = 0;
|
||||||
|
}
|
||||||
|
else if (child_pid)
|
||||||
|
*child_pid = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHILD_CHDIR_FAILED:
|
case CHILD_CHDIR_FAILED:
|
||||||
@ -793,7 +819,6 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
g_strerror (buf[1]));
|
g_strerror (buf[1]));
|
||||||
goto cleanup_and_fail;
|
goto cleanup_and_fail;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Success against all odds! return the information */
|
/* Success against all odds! return the information */
|
||||||
|
|
||||||
@ -804,11 +829,13 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
if (standard_error)
|
if (standard_error)
|
||||||
*standard_error = stderr_pipe[0];
|
*standard_error = stderr_pipe[0];
|
||||||
if (exit_status)
|
if (exit_status)
|
||||||
*exit_status = status;
|
*exit_status = buf[1];
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
cleanup_and_fail:
|
cleanup_and_fail:
|
||||||
|
if (helper != -1)
|
||||||
|
CloseHandle ((HANDLE) helper);
|
||||||
close_and_invalidate (&child_err_report_pipe[0]);
|
close_and_invalidate (&child_err_report_pipe[0]);
|
||||||
close_and_invalidate (&child_err_report_pipe[1]);
|
close_and_invalidate (&child_err_report_pipe[1]);
|
||||||
close_and_invalidate (&stdin_pipe[0]);
|
close_and_invalidate (&stdin_pipe[0]);
|
||||||
|
Loading…
Reference in New Issue
Block a user