mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-17 19:21:58 +02:00
When possible, manage without the helper process. (Part of the
2003-07-31 Tor Lillqvist <tml@iki.fi> * glib/gspawn-win32.c: When possible, manage without the helper process. (Part of the enhancements outlined in #98737.) Speeds up GIMP 1.3's first-time-run plug-in query phase a lot. Plug a file descriptor (and thus Win32 handle) leak: close the read end of the child error report pipe after use.
This commit is contained in:
parent
82911ba375
commit
cdf72b09e6
@ -1,3 +1,12 @@
|
||||
2003-07-31 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* glib/gspawn-win32.c: When possible, manage without the helper
|
||||
process. (Part of the enhancements outlined in #98737.) Speeds up
|
||||
GIMP 1.3's first-time-run plug-in query phase a lot.
|
||||
|
||||
Plug a file descriptor (and thus Win32 handle) leak: close the
|
||||
read end of the child error report pipe after use.
|
||||
|
||||
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
||||
|
@ -1,3 +1,12 @@
|
||||
2003-07-31 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* glib/gspawn-win32.c: When possible, manage without the helper
|
||||
process. (Part of the enhancements outlined in #98737.) Speeds up
|
||||
GIMP 1.3's first-time-run plug-in query phase a lot.
|
||||
|
||||
Plug a file descriptor (and thus Win32 handle) leak: close the
|
||||
read end of the child error report pipe after use.
|
||||
|
||||
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
||||
|
@ -1,3 +1,12 @@
|
||||
2003-07-31 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* glib/gspawn-win32.c: When possible, manage without the helper
|
||||
process. (Part of the enhancements outlined in #98737.) Speeds up
|
||||
GIMP 1.3's first-time-run plug-in query phase a lot.
|
||||
|
||||
Plug a file descriptor (and thus Win32 handle) leak: close the
|
||||
read end of the child error report pipe after use.
|
||||
|
||||
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
||||
|
@ -1,3 +1,12 @@
|
||||
2003-07-31 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* glib/gspawn-win32.c: When possible, manage without the helper
|
||||
process. (Part of the enhancements outlined in #98737.) Speeds up
|
||||
GIMP 1.3's first-time-run plug-in query phase a lot.
|
||||
|
||||
Plug a file descriptor (and thus Win32 handle) leak: close the
|
||||
read end of the child error report pipe after use.
|
||||
|
||||
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
||||
|
@ -1,3 +1,12 @@
|
||||
2003-07-31 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* glib/gspawn-win32.c: When possible, manage without the helper
|
||||
process. (Part of the enhancements outlined in #98737.) Speeds up
|
||||
GIMP 1.3's first-time-run plug-in query phase a lot.
|
||||
|
||||
Plug a file descriptor (and thus Win32 handle) leak: close the
|
||||
read end of the child error report pipe after use.
|
||||
|
||||
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
||||
|
@ -1,3 +1,12 @@
|
||||
2003-07-31 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* glib/gspawn-win32.c: When possible, manage without the helper
|
||||
process. (Part of the enhancements outlined in #98737.) Speeds up
|
||||
GIMP 1.3's first-time-run plug-in query phase a lot.
|
||||
|
||||
Plug a file descriptor (and thus Win32 handle) leak: close the
|
||||
read end of the child error report pipe after use.
|
||||
|
||||
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* gspawn-win32.c - Process launching on Win32
|
||||
*
|
||||
* Copyright 2000 Red Hat, Inc.
|
||||
* Copyright 2003 Tor Lillqvist
|
||||
*
|
||||
* GLib is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
@ -30,17 +31,21 @@
|
||||
* running, and the current directory is common for all threads.)
|
||||
*
|
||||
* Thus, we must in most cases use a helper program to handle closing
|
||||
* of (inherited) file descriptors and changing of directory. In fact,
|
||||
* we do it all the time.
|
||||
* of (inherited) file descriptors and changing of directory. The
|
||||
* helper process is also needed if the standard input, standard
|
||||
* output, or standard error of the process to be run are supposed to
|
||||
* be redirected somewhere.
|
||||
*
|
||||
* The structure of the source code in this file is a mess, I know.
|
||||
*/
|
||||
|
||||
/* FIXME: Actually implement G_SPAWN_FILE_AND_ARGV_ZERO */
|
||||
|
||||
/* Define this to get some logging all the time */
|
||||
/* #define G_SPAWN_WIN32_DEBUG */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "glib.h"
|
||||
#include "gprintfint.h"
|
||||
|
||||
@ -97,6 +102,11 @@ enum {
|
||||
ARG_COUNT = ARG_PROGRAM
|
||||
};
|
||||
|
||||
/* Return codes from do_spawn() */
|
||||
#define DO_SPAWN_ERROR_HELPER -1
|
||||
#define DO_SPAWN_OK_NO_HELPER -2
|
||||
#define DO_SPAWN_ERROR_NO_HELPER -3
|
||||
|
||||
static gint
|
||||
protect_argv (gchar **argv,
|
||||
gchar ***new_argv)
|
||||
@ -189,9 +199,10 @@ static gboolean do_spawn_with_pipes (gboolean dont_wait,
|
||||
gboolean stdout_to_null,
|
||||
gboolean stderr_to_null,
|
||||
gboolean child_inherits_stdin,
|
||||
gboolean file_and_argv_zero,
|
||||
GSpawnChildSetupFunc child_setup,
|
||||
gpointer user_data,
|
||||
gint *child_pid,
|
||||
gint *child_handle,
|
||||
gint *standard_input,
|
||||
gint *standard_output,
|
||||
gint *standard_error,
|
||||
@ -214,7 +225,7 @@ g_spawn_async (const gchar *working_directory,
|
||||
GSpawnFlags flags,
|
||||
GSpawnChildSetupFunc child_setup,
|
||||
gpointer user_data,
|
||||
gint *child_pid,
|
||||
gint *child_handle,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (argv != NULL, FALSE);
|
||||
@ -224,7 +235,7 @@ g_spawn_async (const gchar *working_directory,
|
||||
flags,
|
||||
child_setup,
|
||||
user_data,
|
||||
child_pid,
|
||||
child_handle,
|
||||
NULL, NULL, NULL,
|
||||
error);
|
||||
}
|
||||
@ -345,6 +356,7 @@ g_spawn_sync (const gchar *working_directory,
|
||||
(flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
|
||||
(flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
|
||||
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
||||
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
|
||||
child_setup,
|
||||
user_data,
|
||||
&pid,
|
||||
@ -511,7 +523,7 @@ g_spawn_async_with_pipes (const gchar *working_directory,
|
||||
GSpawnFlags flags,
|
||||
GSpawnChildSetupFunc child_setup,
|
||||
gpointer user_data,
|
||||
gint *child_pid,
|
||||
gint *child_handle,
|
||||
gint *standard_input,
|
||||
gint *standard_output,
|
||||
gint *standard_error,
|
||||
@ -536,9 +548,10 @@ g_spawn_async_with_pipes (const gchar *working_directory,
|
||||
(flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
|
||||
(flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
|
||||
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
||||
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
|
||||
child_setup,
|
||||
user_data,
|
||||
child_pid,
|
||||
child_handle,
|
||||
standard_input,
|
||||
standard_output,
|
||||
standard_error,
|
||||
@ -605,6 +618,14 @@ g_spawn_command_line_async (const gchar *command_line,
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* This stinks, code reorg needed. Presumably do_spawn() should be
|
||||
* inserted into its only caller, do_spawn_with_pipes(), and then code
|
||||
* snippets from that function should be split out to separate
|
||||
* functions if necessary.
|
||||
*/
|
||||
|
||||
static gint shortcut_spawn_retval;
|
||||
|
||||
static gint
|
||||
do_spawn (gboolean dont_wait,
|
||||
gint child_err_report_fd,
|
||||
@ -619,6 +640,7 @@ do_spawn (gboolean dont_wait,
|
||||
gboolean stdout_to_null,
|
||||
gboolean stderr_to_null,
|
||||
gboolean child_inherits_stdin,
|
||||
gboolean file_and_argv_zero,
|
||||
GSpawnChildSetupFunc child_setup,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -630,6 +652,34 @@ do_spawn (gboolean dont_wait,
|
||||
|
||||
SETUP_DEBUG();
|
||||
|
||||
if (stdin_fd == -1 && stdout_fd == -1 && stderr_fd == -1 &&
|
||||
(working_directory == NULL || !*working_directory) &&
|
||||
!close_descriptors &&
|
||||
!stdout_to_null && !stderr_to_null &&
|
||||
child_inherits_stdin)
|
||||
{
|
||||
/* We can do without the helper process */
|
||||
int mode = dont_wait ? P_NOWAIT : P_WAIT;
|
||||
|
||||
if (debug)
|
||||
g_print ("doing without gspawn-win32-helper\n");
|
||||
|
||||
if (search_path)
|
||||
rc = spawnvp (mode, argv[0], argv);
|
||||
else
|
||||
rc = spawnv (mode, argv[0], argv);
|
||||
|
||||
if (rc == -1)
|
||||
{
|
||||
return DO_SPAWN_ERROR_NO_HELPER;
|
||||
}
|
||||
else
|
||||
{
|
||||
shortcut_spawn_retval = rc;
|
||||
return DO_SPAWN_OK_NO_HELPER;
|
||||
}
|
||||
}
|
||||
|
||||
while (argv[argc])
|
||||
++argc;
|
||||
|
||||
@ -808,9 +858,10 @@ do_spawn_with_pipes (gboolean dont_wait,
|
||||
gboolean stdout_to_null,
|
||||
gboolean stderr_to_null,
|
||||
gboolean child_inherits_stdin,
|
||||
gboolean file_and_argv_zero,
|
||||
GSpawnChildSetupFunc child_setup,
|
||||
gpointer user_data,
|
||||
gint *child_pid,
|
||||
gint *child_handle,
|
||||
gint *standard_input,
|
||||
gint *standard_output,
|
||||
gint *standard_error,
|
||||
@ -855,6 +906,7 @@ do_spawn_with_pipes (gboolean dont_wait,
|
||||
stdout_to_null,
|
||||
stderr_to_null,
|
||||
child_inherits_stdin,
|
||||
file_and_argv_zero,
|
||||
child_setup,
|
||||
user_data);
|
||||
|
||||
@ -862,8 +914,8 @@ do_spawn_with_pipes (gboolean dont_wait,
|
||||
g_free (new_argv[i]);
|
||||
g_free (new_argv);
|
||||
|
||||
/* do_spawn() returns -1 if gspawn-win32-helper couldn't be run */
|
||||
if (helper == -1)
|
||||
/* Check if gspawn-win32-helper couldn't be run */
|
||||
if (helper == DO_SPAWN_ERROR_HELPER)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_SPAWN_ERROR,
|
||||
@ -872,29 +924,52 @@ do_spawn_with_pipes (gboolean dont_wait,
|
||||
goto cleanup_and_fail;
|
||||
}
|
||||
|
||||
else if (helper == DO_SPAWN_OK_NO_HELPER)
|
||||
{
|
||||
if (child_handle && dont_wait && !dont_return_handle)
|
||||
*child_handle = shortcut_spawn_retval;
|
||||
else if (!dont_wait && exit_status)
|
||||
*exit_status = shortcut_spawn_retval;
|
||||
|
||||
close_and_invalidate (&child_err_report_pipe[0]);
|
||||
close_and_invalidate (&child_err_report_pipe[1]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (helper == DO_SPAWN_ERROR_NO_HELPER)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_SPAWN_ERROR,
|
||||
G_SPAWN_ERROR_FAILED,
|
||||
_("Failed to execute child process (%s)"),
|
||||
g_strerror (errno));
|
||||
helper = -1;
|
||||
goto cleanup_and_fail;
|
||||
}
|
||||
|
||||
if (!read_ints (child_err_report_pipe[0],
|
||||
buf, 2, &n_ints,
|
||||
error) ||
|
||||
n_ints != 2)
|
||||
n_ints != 2)
|
||||
goto cleanup_and_fail;
|
||||
|
||||
/* Error code from gspawn-win32-helper. */
|
||||
switch (buf[0])
|
||||
{
|
||||
case CHILD_NO_ERROR:
|
||||
if (child_pid && dont_wait && !dont_return_handle)
|
||||
if (child_handle && dont_wait && !dont_return_handle)
|
||||
{
|
||||
/* 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,
|
||||
GetCurrentProcess (), (LPHANDLE) child_handle,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
*child_pid = 0;
|
||||
*child_handle = 0;
|
||||
}
|
||||
else if (child_pid)
|
||||
*child_pid = 0;
|
||||
else if (child_handle)
|
||||
*child_handle = 0;
|
||||
break;
|
||||
|
||||
case CHILD_CHDIR_FAILED:
|
||||
@ -927,6 +1002,8 @@ do_spawn_with_pipes (gboolean dont_wait,
|
||||
*exit_status = buf[1];
|
||||
CloseHandle ((HANDLE) helper);
|
||||
|
||||
close_and_invalidate (&child_err_report_pipe[0]);
|
||||
|
||||
return TRUE;
|
||||
|
||||
cleanup_and_fail:
|
||||
|
Loading…
x
Reference in New Issue
Block a user