mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-12-05 16:14:49 +01:00
New internal function.
2008-02-24 Tor Lillqvist <tml@novell.com> * glib/gutils.c (_glib_get_installation_directory): New internal function. * glib/gspawn-win32.c: When spawning the helper process, use an explicit full path. (#518292) * glib/gspawn-win32.c * glib/gspawn-win32-helper.c: Fix race condition when using the helper process: When the helper process writes the handle of the actual started user process to the parent process, it must be duplicated in the parent process with DuplicateHandle() so that it is a valid handle in that process. However, if the helper process has happened to exit before the DuplicateHandle() call, the duplication will fail. Thus we must synchronise the helper process's exit. Use another pipe for this. Take care not to inherit the writing end of this pipe to the helper process. Also, in the helper process, take care not to inherit either of the pipes used for communication with the parent process to the started user process. svn path=/trunk/; revision=6575
This commit is contained in:
committed by
Tor Lillqvist
parent
3bd512643d
commit
17640e78d3
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#include "glib.h"
|
||||
#define GSPAWN_HELPER
|
||||
@@ -151,7 +153,8 @@ WinMain (struct HINSTANCE__ *hInstance,
|
||||
char *lpszCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
int child_err_report_fd;
|
||||
int child_err_report_fd = -1;
|
||||
int helper_sync_fd = -1;
|
||||
int i;
|
||||
int fd;
|
||||
int mode;
|
||||
@@ -164,6 +167,7 @@ WinMain (struct HINSTANCE__ *hInstance,
|
||||
int argc;
|
||||
wchar_t **wargv, **wenvp;
|
||||
_startupinfo si = { 0 };
|
||||
char c;
|
||||
|
||||
g_assert (__argc >= ARG_COUNT);
|
||||
|
||||
@@ -188,6 +192,14 @@ WinMain (struct HINSTANCE__ *hInstance,
|
||||
if (__argv[ARG_CHILD_ERR_REPORT][strlen (__argv[ARG_CHILD_ERR_REPORT]) - 1] == '#')
|
||||
argv_zero_offset++;
|
||||
|
||||
/* argv[ARG_HELPER_SYNC] is the file descriptor number we read a
|
||||
* byte that tells us it is OK to exit. We have to wait until the
|
||||
* parent allows us to exit, so that the parent has had time to
|
||||
* duplicate the process handle we sent it. Duplicating a handle
|
||||
* from another process works only if that other process exists.
|
||||
*/
|
||||
helper_sync_fd = atoi (__argv[ARG_HELPER_SYNC]);
|
||||
|
||||
/* argv[ARG_STDIN..ARG_STDERR] are the file descriptor numbers that
|
||||
* should be dup2'd to 0, 1 and 2. '-' if the corresponding fd
|
||||
* should be left alone, and 'z' if it should be connected to the
|
||||
@@ -270,9 +282,15 @@ WinMain (struct HINSTANCE__ *hInstance,
|
||||
*/
|
||||
if (__argv[ARG_CLOSE_DESCRIPTORS][0] == 'y')
|
||||
for (i = 3; i < 1000; i++) /* FIXME real limit? */
|
||||
if (i != child_err_report_fd)
|
||||
if (i != child_err_report_fd && i != helper_sync_fd)
|
||||
close (i);
|
||||
|
||||
/* We don't want our child to inherit the error report and
|
||||
* helper sync fds.
|
||||
*/
|
||||
child_err_report_fd = dup_noninherited (child_err_report_fd, _O_WRONLY);
|
||||
helper_sync_fd = dup_noninherited (helper_sync_fd, _O_RDONLY);
|
||||
|
||||
/* __argv[ARG_WAIT] is "w" to wait for the program to exit */
|
||||
if (__argv[ARG_WAIT][0] == 'w')
|
||||
mode = P_WAIT;
|
||||
@@ -307,5 +325,8 @@ WinMain (struct HINSTANCE__ *hInstance,
|
||||
write (child_err_report_fd, &handle, sizeof (handle));
|
||||
else
|
||||
write (child_err_report_fd, &zero, sizeof (zero));
|
||||
|
||||
read (helper_sync_fd, &c, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user