Re: glib 2.3.3 and Windows
- From: "J. Ali Harlow" <ali juiblex co uk>
- To: Owen Taylor <otaylor redhat com>, Tor Lillqvist <tml iki fi>
- Cc: Hans Breuer <Hans Breuer org>, gtk-devel-list gnome org
- Subject: Re: glib 2.3.3 and Windows
- Date: Mon, 1 Mar 2004 15:32:20 +0000
On 2004.03.01 13:35 J. Ali Harlow wrote:
Owen,
I've now implemented this. I've tested with child-test and spawn-test
under Linux, and child-test under WIN32. Unfortunately, spawn-test
doesn't work for me under WIN32 (this is before my changes), so I'm
not able to test this bit. Something to worry about later, I think.
Of course, it would help if I actually attached the patch.
If you want me, I'm hiding under this nice rock over here.
Ali.
# $Product: glib $ $Id$
diff -Naurd ../cvs/glib/configure.in ./configure.in
--- ../cvs/glib/configure.in Fri Feb 27 10:34:19 2004
+++ ./configure.in Mon Mar 1 13:10:16 2004
@@ -131,7 +131,7 @@
GOBJECT_DEF=gobject.def
GTHREAD_DEF=gthread.def
TESTGMODULE_EXP=testgmodule.exp
- glib_pid_type=HANDLE
+ glib_pid_type='void *'
;;
*)
glib_native_win32=no
diff -Naurd ../cvs/glib/glib/gmain.c ./glib/gmain.c
--- ../cvs/glib/glib/gmain.c Mon Mar 1 08:53:35 2004
+++ ./glib/gmain.c Mon Mar 1 13:10:16 2004
@@ -3370,6 +3370,10 @@
(child_watch_callback) (child_watch_source->pid, child_watch_source->child_status, user_data);
+#ifdef G_OS_WIN32
+ CloseHandle (child_watch_source->pid);
+#endif
+
/* We never keep a child watch source around as the child is gone */
return FALSE;
}
@@ -3492,6 +3496,15 @@
* The source will not initially be associated with any #GMainContext
* and must be added to one with g_source_attach() before it will be
* executed.
+ *
+ * A copy of @pid will be taken. On platforms where #GPid represents
+ * a resource, the caller must close @pid to prevent leaks. If @pid
+ * originates from GLib, g_spawn_close_pid() should be used for this
+ * purpose.
+ *
+ * Care must be taken not to key off the value of the pid that will be passed
+ * to the callback function, since on some platforms it will have a different
+ * value to @pid.
*
* Return value: the newly-created child watch source
*
@@ -3504,15 +3517,24 @@
GChildWatchSource *child_watch_source = (GChildWatchSource *)source;
#ifdef G_OS_WIN32
- child_watch_source->poll.fd = (int)pid;
+ if (!DuplicateHandle (GetCurrentProcess(), pid, GetCurrentProcess(), &child_watch_source->pid, 0, FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ gchar *emsg = g_win32_error_message (GetLastError ());
+ g_warning (G_STRLOC ": DuplicateHandle() failed: %s", emsg);
+ g_free (emsg);
+
+ return NULL;
+ }
+
+ child_watch_source->poll.fd = (int)child_watch_source->pid;
child_watch_source->poll.events = G_IO_IN;
g_source_add_poll (source, &child_watch_source->poll);
#else /* G_OS_WIN32 */
g_child_watch_source_init ();
-#endif /* G_OS_WIN32 */
child_watch_source->pid = pid;
+#endif /* G_OS_WIN32 */
return source;
}
@@ -3528,6 +3550,14 @@
*
* Sets a function to be called when the child indicated by @pid exits, at a
* default priority, #G_PRIORITY_DEFAULT.
+ *
+ * A copy of @pid will be taken. On platforms where #GPid represents
+ * a resource, the caller must close @pid to prevent leaks. If @pid
+ * originates from GLib, g_spawn_close_pid() should be used for this
+ * purpose.
+ *
+ * Care must be taken not to key off the value of the pid that will be passed
+ * to @function, since on some platforms it will have a different value to @pid.
*
* Return value: the id of event source.
*
@@ -3566,6 +3596,14 @@
* Sets a function to be called when the child indicated by @pid exits, at a
* default priority, #G_PRIORITY_DEFAULT.
*
+ * A copy of @pid will be taken. On platforms where #GPid represents
+ * a resource, the caller must close @pid to prevent leaks. If @pid
+ * originates from GLib, g_spawn_close_pid() should be used for this
+ * purpose.
+ *
+ * Care must be taken not to key off the value of the pid that will be passed
+ * to @function, since on some platforms it will have a different value to @pid.
+ *
* Return value: the id of event source.
*
* Since: 2.4
diff -Naurd ../cvs/glib/glib/gspawn.h ./glib/gspawn.h
--- ../cvs/glib/glib/gspawn.h Tue Jun 26 17:01:14 2001
+++ ./glib/gspawn.h Mon Mar 1 13:10:16 2004
@@ -77,7 +77,7 @@
GSpawnFlags flags,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_pid,
+ GPid *child_pid,
GError **error);
@@ -90,7 +90,7 @@
GSpawnFlags flags,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_pid,
+ GPid *child_pid,
gint *standard_input,
gint *standard_output,
gint *standard_error,
@@ -120,6 +120,8 @@
gboolean g_spawn_command_line_async (const gchar *command_line,
GError **error);
+void g_spawn_close_pid (GPid pid);
+
G_END_DECLS
diff -Naurd ../cvs/glib/glib/gspawn.c ./glib/gspawn.c
--- ../cvs/glib/glib/gspawn.c Fri Jul 25 22:32:47 2003
+++ ./glib/gspawn.c Mon Mar 1 13:10:16 2004
@@ -58,7 +58,7 @@
gboolean file_and_argv_zero,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_pid,
+ GPid *child_pid,
gint *standard_input,
gint *standard_output,
gint *standard_error,
@@ -96,7 +96,7 @@
GSpawnFlags flags,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_pid,
+ GPid *child_pid,
GError **error)
{
g_return_val_if_fail (argv != NULL, FALSE);
@@ -213,7 +213,7 @@
{
gint outpipe = -1;
gint errpipe = -1;
- gint pid;
+ GPid pid;
fd_set fds;
gint ret;
GString *outstr = NULL;
@@ -535,6 +535,9 @@
*
* If an error occurs, @child_pid, @standard_input, @standard_output,
* and @standard_error will not be filled with valid values.
+ *
+ * If @child_pid is not %NULL and an error does not occur then the returned
+ * pid must be closed using g_spawn_close_pid().
*
* Return value: %TRUE on success, %FALSE if an error was set
**/
@@ -545,7 +548,7 @@
GSpawnFlags flags,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_pid,
+ GPid *child_pid,
gint *standard_input,
gint *standard_output,
gint *standard_error,
@@ -1024,13 +1027,13 @@
gboolean file_and_argv_zero,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_pid,
+ GPid *child_pid,
gint *standard_input,
gint *standard_output,
gint *standard_error,
GError **error)
{
- gint pid = -1;
+ GPid pid = -1;
gint stdin_pipe[2] = { -1, -1 };
gint stdout_pipe[2] = { -1, -1 };
gint stderr_pipe[2] = { -1, -1 };
@@ -1093,7 +1096,7 @@
* is to exit, so we can waitpid() it immediately.
* Then the grandchild will not become a zombie.
*/
- gint grandchild_pid;
+ GPid grandchild_pid;
grandchild_pid = fork ();
@@ -1517,3 +1520,17 @@
/* Return the error from the last attempt (probably ENOENT). */
return -1;
}
+
+/**
+ * g_spawn_close_pid:
+ * @pid: The process identifier to close
+ *
+ * On some platforms, notably WIN32, the #GPid type represents a resource
+ * which must be closed to prevent resource leaking. g_spawn_close_pid()
+ * is provided for this purpose. It should be used on all platforms, even
+ * though it doesn't do anything under UNIX.
+ **/
+void
+g_spawn_close_pid (GPid pid)
+{
+}
diff -Naurd ../cvs/glib/glib/gspawn-win32.c ./glib/gspawn-win32.c
--- ../cvs/glib/glib/gspawn-win32.c Tue Sep 30 21:04:51 2003
+++ ./glib/gspawn-win32.c Mon Mar 1 13:10:16 2004
@@ -202,7 +202,7 @@
gboolean file_and_argv_zero,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_handle,
+ GPid *child_handle,
gint *standard_input,
gint *standard_output,
gint *standard_error,
@@ -225,7 +225,7 @@
GSpawnFlags flags,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_handle,
+ GPid *child_handle,
GError **error)
{
g_return_val_if_fail (argv != NULL, FALSE);
@@ -316,7 +316,7 @@
{
gint outpipe = -1;
gint errpipe = -1;
- gint pid;
+ GPid pid;
GIOChannel *outchannel = NULL;
GIOChannel *errchannel = NULL;
GPollFD outfd, errfd;
@@ -492,6 +492,8 @@
if (errpipe >= 0)
close_and_invalidate (&errpipe);
+ g_spawn_close_pid(pid);
+
if (failed)
{
if (outstr)
@@ -523,7 +525,7 @@
GSpawnFlags flags,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_handle,
+ GPid *child_handle,
gint *standard_input,
gint *standard_output,
gint *standard_error,
@@ -869,7 +871,7 @@
gboolean file_and_argv_zero,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
- gint *child_handle,
+ GPid *child_handle,
gint *standard_input,
gint *standard_output,
gint *standard_error,
@@ -1036,5 +1038,10 @@
else
return TRUE;
}
-
#endif /* !GSPAWN_HELPER */
+
+void
+g_spawn_close_pid (GPid pid)
+{
+ CloseHandle (pid);
+}
diff -Naurd ../cvs/glib/tests/child-test.c ./tests/child-test.c
--- ../cvs/glib/tests/child-test.c Mon Mar 1 08:53:36 2004
+++ ./tests/child-test.c Mon Mar 1 13:10:16 2004
@@ -86,12 +86,12 @@
gboolean
child_watch_callback (GPid pid, gint status, gpointer data)
{
+ gint ttl = GPOINTER_TO_INT (data);
+
#ifndef G_OS_WIN32
- g_print ("child %d exited, status %d\n", pid, status);
+ g_print ("child %d (ttl %d) exited, status %d\n", pid, ttl, status);
#else
- g_print ("child %p exited, status %d\n", pid, status);
-
- CloseHandle(pid);
+ g_print ("child %p (ttl %d) exited, status %d\n", pid, ttl, status);
#endif
if (--alive == 0)
@@ -112,14 +112,15 @@
pid = get_a_child (ttl);
source = g_child_watch_source_new (pid);
- g_source_set_callback (source, (GSourceFunc) child_watch_callback, NULL, NULL);
+ g_source_set_callback (source, (GSourceFunc) child_watch_callback, data, NULL);
g_source_attach (source, g_main_loop_get_context (new_main_loop));
g_source_unref (source);
#ifdef G_OS_WIN32
- g_print ("whee! created pid: %p\n", pid);
+ g_print ("whee! created pid: %p (ttl %d)\n", pid, ttl);
+ CloseHandle(pid);
#else
- g_print ("whee! created pid: %d\n", pid);
+ g_print ("whee! created pid: %d (ttl %d)\n", pid, ttl);
#endif
g_main_loop_run (new_main_loop);
diff -Naurd ../cvs/glib/glib/glib.def ./glib/glib.def
--- ../cvs/glib/glib/glib.def Mon Mar 1 10:56:49 2004
+++ ./glib/glib.def Mon Mar 1 15:21:39 2004
@@ -579,6 +579,7 @@
g_spaced_primes_closest
g_spawn_async
g_spawn_async_with_pipes
+ g_spawn_close_pid
g_spawn_command_line_async
g_spawn_command_line_sync
g_spawn_error_quark
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]