mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-20 04:22:11 +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>
|
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
* 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>
|
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
* 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>
|
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
* 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>
|
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
* 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>
|
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
* 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>
|
2003-07-30 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* glib/gutils.c (g_unsetenv): Use same argument name as in header, to pacify gtk-doc.
|
* 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
|
/* gspawn-win32.c - Process launching on Win32
|
||||||
*
|
*
|
||||||
* Copyright 2000 Red Hat, Inc.
|
* Copyright 2000 Red Hat, Inc.
|
||||||
|
* Copyright 2003 Tor Lillqvist
|
||||||
*
|
*
|
||||||
* GLib is free software; you can redistribute it and/or
|
* GLib is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License as
|
* 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.)
|
* running, and the current directory is common for all threads.)
|
||||||
*
|
*
|
||||||
* Thus, we must in most cases use a helper program to handle closing
|
* Thus, we must in most cases use a helper program to handle closing
|
||||||
* of (inherited) file descriptors and changing of directory. In fact,
|
* of (inherited) file descriptors and changing of directory. The
|
||||||
* we do it all the time.
|
* 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 this to get some logging all the time */
|
||||||
/* #define G_SPAWN_WIN32_DEBUG */
|
/* #define G_SPAWN_WIN32_DEBUG */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include "gprintfint.h"
|
#include "gprintfint.h"
|
||||||
|
|
||||||
@ -97,6 +102,11 @@ enum {
|
|||||||
ARG_COUNT = ARG_PROGRAM
|
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
|
static gint
|
||||||
protect_argv (gchar **argv,
|
protect_argv (gchar **argv,
|
||||||
gchar ***new_argv)
|
gchar ***new_argv)
|
||||||
@ -189,9 +199,10 @@ static gboolean do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
gboolean stdout_to_null,
|
gboolean stdout_to_null,
|
||||||
gboolean stderr_to_null,
|
gboolean stderr_to_null,
|
||||||
gboolean child_inherits_stdin,
|
gboolean child_inherits_stdin,
|
||||||
|
gboolean file_and_argv_zero,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gint *child_pid,
|
gint *child_handle,
|
||||||
gint *standard_input,
|
gint *standard_input,
|
||||||
gint *standard_output,
|
gint *standard_output,
|
||||||
gint *standard_error,
|
gint *standard_error,
|
||||||
@ -214,7 +225,7 @@ g_spawn_async (const gchar *working_directory,
|
|||||||
GSpawnFlags flags,
|
GSpawnFlags flags,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gint *child_pid,
|
gint *child_handle,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (argv != NULL, FALSE);
|
g_return_val_if_fail (argv != NULL, FALSE);
|
||||||
@ -224,7 +235,7 @@ g_spawn_async (const gchar *working_directory,
|
|||||||
flags,
|
flags,
|
||||||
child_setup,
|
child_setup,
|
||||||
user_data,
|
user_data,
|
||||||
child_pid,
|
child_handle,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
@ -345,6 +356,7 @@ g_spawn_sync (const gchar *working_directory,
|
|||||||
(flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
|
(flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
|
||||||
(flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
|
(flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
|
||||||
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
||||||
|
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
|
||||||
child_setup,
|
child_setup,
|
||||||
user_data,
|
user_data,
|
||||||
&pid,
|
&pid,
|
||||||
@ -511,7 +523,7 @@ g_spawn_async_with_pipes (const gchar *working_directory,
|
|||||||
GSpawnFlags flags,
|
GSpawnFlags flags,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gint *child_pid,
|
gint *child_handle,
|
||||||
gint *standard_input,
|
gint *standard_input,
|
||||||
gint *standard_output,
|
gint *standard_output,
|
||||||
gint *standard_error,
|
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_STDOUT_TO_DEV_NULL) != 0,
|
||||||
(flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
|
(flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
|
||||||
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
||||||
|
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
|
||||||
child_setup,
|
child_setup,
|
||||||
user_data,
|
user_data,
|
||||||
child_pid,
|
child_handle,
|
||||||
standard_input,
|
standard_input,
|
||||||
standard_output,
|
standard_output,
|
||||||
standard_error,
|
standard_error,
|
||||||
@ -605,6 +618,14 @@ g_spawn_command_line_async (const gchar *command_line,
|
|||||||
return retval;
|
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
|
static gint
|
||||||
do_spawn (gboolean dont_wait,
|
do_spawn (gboolean dont_wait,
|
||||||
gint child_err_report_fd,
|
gint child_err_report_fd,
|
||||||
@ -619,6 +640,7 @@ do_spawn (gboolean dont_wait,
|
|||||||
gboolean stdout_to_null,
|
gboolean stdout_to_null,
|
||||||
gboolean stderr_to_null,
|
gboolean stderr_to_null,
|
||||||
gboolean child_inherits_stdin,
|
gboolean child_inherits_stdin,
|
||||||
|
gboolean file_and_argv_zero,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
@ -630,6 +652,34 @@ do_spawn (gboolean dont_wait,
|
|||||||
|
|
||||||
SETUP_DEBUG();
|
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])
|
while (argv[argc])
|
||||||
++argc;
|
++argc;
|
||||||
|
|
||||||
@ -808,9 +858,10 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
gboolean stdout_to_null,
|
gboolean stdout_to_null,
|
||||||
gboolean stderr_to_null,
|
gboolean stderr_to_null,
|
||||||
gboolean child_inherits_stdin,
|
gboolean child_inherits_stdin,
|
||||||
|
gboolean file_and_argv_zero,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gint *child_pid,
|
gint *child_handle,
|
||||||
gint *standard_input,
|
gint *standard_input,
|
||||||
gint *standard_output,
|
gint *standard_output,
|
||||||
gint *standard_error,
|
gint *standard_error,
|
||||||
@ -855,6 +906,7 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
stdout_to_null,
|
stdout_to_null,
|
||||||
stderr_to_null,
|
stderr_to_null,
|
||||||
child_inherits_stdin,
|
child_inherits_stdin,
|
||||||
|
file_and_argv_zero,
|
||||||
child_setup,
|
child_setup,
|
||||||
user_data);
|
user_data);
|
||||||
|
|
||||||
@ -862,8 +914,8 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
g_free (new_argv[i]);
|
g_free (new_argv[i]);
|
||||||
g_free (new_argv);
|
g_free (new_argv);
|
||||||
|
|
||||||
/* do_spawn() returns -1 if gspawn-win32-helper couldn't be run */
|
/* Check if gspawn-win32-helper couldn't be run */
|
||||||
if (helper == -1)
|
if (helper == DO_SPAWN_ERROR_HELPER)
|
||||||
{
|
{
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_SPAWN_ERROR,
|
G_SPAWN_ERROR,
|
||||||
@ -872,6 +924,29 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
goto cleanup_and_fail;
|
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],
|
if (!read_ints (child_err_report_pipe[0],
|
||||||
buf, 2, &n_ints,
|
buf, 2, &n_ints,
|
||||||
error) ||
|
error) ||
|
||||||
@ -882,19 +957,19 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
switch (buf[0])
|
switch (buf[0])
|
||||||
{
|
{
|
||||||
case CHILD_NO_ERROR:
|
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
|
/* helper is our HANDLE for gspawn-win32-helper. It has
|
||||||
* told us the HANDLE of its child. Duplicate that into
|
* told us the HANDLE of its child. Duplicate that into
|
||||||
* a HANDLE valid in this process.
|
* a HANDLE valid in this process.
|
||||||
*/
|
*/
|
||||||
if (!DuplicateHandle ((HANDLE) helper, (HANDLE) buf[1],
|
if (!DuplicateHandle ((HANDLE) helper, (HANDLE) buf[1],
|
||||||
GetCurrentProcess (), (LPHANDLE) child_pid,
|
GetCurrentProcess (), (LPHANDLE) child_handle,
|
||||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
*child_pid = 0;
|
*child_handle = 0;
|
||||||
}
|
}
|
||||||
else if (child_pid)
|
else if (child_handle)
|
||||||
*child_pid = 0;
|
*child_handle = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHILD_CHDIR_FAILED:
|
case CHILD_CHDIR_FAILED:
|
||||||
@ -927,6 +1002,8 @@ do_spawn_with_pipes (gboolean dont_wait,
|
|||||||
*exit_status = buf[1];
|
*exit_status = buf[1];
|
||||||
CloseHandle ((HANDLE) helper);
|
CloseHandle ((HANDLE) helper);
|
||||||
|
|
||||||
|
close_and_invalidate (&child_err_report_pipe[0]);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
cleanup_and_fail:
|
cleanup_and_fail:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user