Index: glib.symbols
===================================================================
--- glib.symbols	(revision 5255)
+++ glib.symbols	(working copy)
@@ -972,6 +972,7 @@
 #if IN_FILE(__G_SPAWN_C__)
 g_spawn_async PRIVATE
 g_spawn_async_with_pipes PRIVATE
+g_spawn_async_with_pipes_full PRIVATE
 g_spawn_close_pid
 g_spawn_command_line_async PRIVATE
 g_spawn_command_line_sync PRIVATE
Index: gspawn.c
===================================================================
--- gspawn.c	(revision 5255)
+++ gspawn.c	(working copy)
@@ -45,25 +45,26 @@
                        gchar **envp,
                        gboolean search_path);
 
-static gboolean make_pipe            (gint                  p[2],
-                                      GError              **error);
-static gboolean fork_exec_with_pipes (gboolean              intermediate_child,
-                                      const gchar          *working_directory,
-                                      gchar               **argv,
-                                      gchar               **envp,
-                                      gboolean              close_descriptors,
-                                      gboolean              search_path,
-                                      gboolean              stdout_to_null,
-                                      gboolean              stderr_to_null,
-                                      gboolean              child_inherits_stdin,
-                                      gboolean              file_and_argv_zero,
-                                      GSpawnChildSetupFunc  child_setup,
-                                      gpointer              user_data,
-                                      GPid                 *child_pid,
-                                      gint                 *standard_input,
-                                      gint                 *standard_output,
-                                      gint                 *standard_error,
-                                      GError              **error);
+static gboolean make_pipe            (gint                   p[2],
+                                      GError               **error);
+static gboolean fork_exec_with_pipes (gboolean               intermediate_child,
+                                      const gchar           *working_directory,
+                                      gchar                **argv,
+                                      gchar                **envp,
+                                      gboolean               close_descriptors,
+                                      gboolean               search_path,
+                                      gboolean               stdout_to_null,
+                                      gboolean               stderr_to_null,
+                                      gboolean               child_inherits_stdin,
+                                      gboolean               file_and_argv_zero,
+                                      GSpawnChildSetupFunc   child_setup,
+                                      gpointer               user_data,
+                                      GPid                  *child_pid,
+                                      gint                  *standard_input,
+                                      gint                  *standard_output,
+                                      gint                  *standard_error,
+				      gint                  *waitpid_status,
+                                      GError               **error);
 
 GQuark
 g_spawn_error_quark (void)
@@ -255,6 +256,7 @@
                              NULL,
                              standard_output ? &outpipe : NULL,
                              standard_error ? &errpipe : NULL,
+                             NULL,
                              error))
     return FALSE;
 
@@ -411,7 +413,7 @@
 }
 
 /**
- * g_spawn_async_with_pipes:
+ * g_spawn_async_with_pipes_full:
  * @working_directory: child's current working directory, or %NULL to inherit parent's, in the GLib file name encoding
  * @argv: child's argument vector, in the GLib file name encoding
  * @envp: child's environment, or %NULL to inherit parent's, in the GLib file name encoding
@@ -422,6 +424,7 @@
  * @standard_input: return location for file descriptor to write to child's stdin, or %NULL
  * @standard_output: return location for file descriptor to read child's stdout, or %NULL
  * @standard_error: return location for file descriptor to read child's stderr, or %NULL
+ * @waitpid_status: return location for file descriptor to read child waitpid() return status, or %NULL
  * @error: return location for error
  *
  * Executes a child program asynchronously (your program will not
@@ -575,6 +578,34 @@
                           gint                 *standard_error,
                           GError              **error)
 {
+  return g_spawn_async_with_pipes_full (working_directory,
+					argv,
+					envp,
+					flags,
+					child_setup,
+					user_data,
+					child_pid,
+					standard_input,
+					standard_output,
+					standard_error,
+					NULL,
+					error);
+}
+
+gboolean
+g_spawn_async_with_pipes_full (const gchar          *working_directory,
+			       gchar               **argv,
+			       gchar               **envp,
+			       GSpawnFlags           flags,
+			       GSpawnChildSetupFunc  child_setup,
+			       gpointer              user_data,
+			       GPid                 *child_pid,
+			       gint                 *standard_input,
+			       gint                 *standard_output,
+			       gint                 *standard_error,
+			       gint		    *waitpid_status,
+			       GError              **error)
+{
   g_return_val_if_fail (argv != NULL, FALSE);
   g_return_val_if_fail (standard_output == NULL ||
                         !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
@@ -584,7 +615,7 @@
   g_return_val_if_fail (standard_input == NULL ||
                         !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE);
   
-  return fork_exec_with_pipes (!(flags & G_SPAWN_DO_NOT_REAP_CHILD),
+  return fork_exec_with_pipes ((!(flags & G_SPAWN_DO_NOT_REAP_CHILD) || waitpid_status),
                                working_directory,
                                argv,
                                envp,
@@ -600,6 +631,7 @@
                                standard_input,
                                standard_output,
                                standard_error,
+			       waitpid_status,
                                error);
 }
 
@@ -1057,30 +1089,39 @@
 }
 
 static gboolean
-fork_exec_with_pipes (gboolean              intermediate_child,
-                      const gchar          *working_directory,
-                      gchar               **argv,
-                      gchar               **envp,
-                      gboolean              close_descriptors,
-                      gboolean              search_path,
-                      gboolean              stdout_to_null,
-                      gboolean              stderr_to_null,
-                      gboolean              child_inherits_stdin,
-                      gboolean              file_and_argv_zero,
-                      GSpawnChildSetupFunc  child_setup,
-                      gpointer              user_data,
-                      GPid                 *child_pid,
-                      gint                 *standard_input,
-                      gint                 *standard_output,
-                      gint                 *standard_error,
-                      GError              **error)     
+child_report_handler (GIOChannel *source,
+		      GIOCondition condition,
+		      gpointer data)
 {
+}
+
+static gboolean
+fork_exec_with_pipes (gboolean               intermediate_child,
+                      const gchar           *working_directory,
+                      gchar                **argv,
+                      gchar                **envp,
+                      gboolean               close_descriptors,
+                      gboolean               search_path,
+                      gboolean               stdout_to_null,
+                      gboolean               stderr_to_null,
+                      gboolean               child_inherits_stdin,
+                      gboolean               file_and_argv_zero,
+                      GSpawnChildSetupFunc   child_setup,
+                      gpointer               user_data,
+                      GPid                  *child_pid,
+                      gint                  *standard_input,
+                      gint                  *standard_output,
+                      gint                  *standard_error,
+                      gint                  *waitpid_status,
+                      GError               **error)     
+{
   GPid pid = -1;
   gint stdin_pipe[2] = { -1, -1 };
   gint stdout_pipe[2] = { -1, -1 };
   gint stderr_pipe[2] = { -1, -1 };
   gint child_err_report_pipe[2] = { -1, -1 };
   gint child_pid_report_pipe[2] = { -1, -1 };
+  gint child_status_report_pipe[2] = { -1, -1 };
   gint status;
   
   if (!make_pipe (child_err_report_pipe, error))
@@ -1089,6 +1130,9 @@
   if (intermediate_child && !make_pipe (child_pid_report_pipe, error))
     goto cleanup_and_fail;
   
+  if (waitpid_status && !make_pipe (child_status_report_pipe, error))
+    goto cleanup_and_fail;
+
   if (standard_input && !make_pipe (stdin_pipe, error))
     goto cleanup_and_fail;
   
@@ -1127,6 +1171,7 @@
        */
       close_and_invalidate (&child_err_report_pipe[0]);
       close_and_invalidate (&child_pid_report_pipe[0]);
+      close_and_invalidate (&child_status_report_pipe[0]);
       close_and_invalidate (&stdin_pipe[1]);
       close_and_invalidate (&stdout_pipe[0]);
       close_and_invalidate (&stderr_pipe[0]);
@@ -1172,10 +1217,30 @@
           else
             {
               write_all (child_pid_report_pipe[1], &grandchild_pid, sizeof(grandchild_pid));
-              close_and_invalidate (&child_pid_report_pipe[1]);
+	      close_and_invalidate (&child_pid_report_pipe[1]);
               
-              _exit (0);
-            }
+              if (waitpid_status) 
+                {
+                wait_again_grandchild:
+                  if (waitpid (grandchild_pid, &status, 0) < 0)
+                    {
+                      if (errno == EINTR)
+                        goto wait_again_grandchild;
+                      else if (errno == ECHILD)
+                        ; /* FIXME: child already reaped */
+                      else
+                        g_warning ("waitpid() should not fail in "
+                                   "'fork_exec_with_pipes'");
+                    }
+		  write_all (child_status_report_pipe[1], &status, sizeof(status));
+		  close_and_invalidate (&child_status_report_pipe[1]);
+                  _exit (0);
+                }
+              else
+                {      
+                  _exit (0);
+                }
+             }
         }
       else
         {
@@ -1209,12 +1274,13 @@
       /* Close the uncared-about ends of the pipes */
       close_and_invalidate (&child_err_report_pipe[1]);
       close_and_invalidate (&child_pid_report_pipe[1]);
+      close_and_invalidate (&child_status_report_pipe[1]);
       close_and_invalidate (&stdin_pipe[0]);
       close_and_invalidate (&stdout_pipe[1]);
       close_and_invalidate (&stderr_pipe[1]);
 
       /* If we had an intermediate child, reap it */
-      if (intermediate_child)
+      if (intermediate_child && !waitpid_status)
         {
         wait_again:
           if (waitpid (pid, &status, 0) < 0)
@@ -1328,6 +1394,8 @@
         *standard_output = stdout_pipe[0];
       if (standard_error)
         *standard_error = stderr_pipe[0];
+      if (waitpid_status) 
+	*waitpid_status = child_status_report_pipe[0];
       
       return TRUE;
     }
@@ -1357,6 +1425,8 @@
   close_and_invalidate (&child_err_report_pipe[1]);
   close_and_invalidate (&child_pid_report_pipe[0]);
   close_and_invalidate (&child_pid_report_pipe[1]);
+  close_and_invalidate (&child_status_report_pipe[0]);
+  close_and_invalidate (&child_status_report_pipe[1]);
   close_and_invalidate (&stdin_pipe[0]);
   close_and_invalidate (&stdin_pipe[1]);
   close_and_invalidate (&stdout_pipe[0]);
Index: gspawn.h
===================================================================
--- gspawn.h	(revision 5255)
+++ gspawn.h	(working copy)
@@ -104,6 +104,18 @@
                                    gint                 *standard_error,
                                    GError              **error);
 
+gboolean g_spawn_async_with_pipes_full (const gchar          *working_directory,
+					gchar               **argv,
+					gchar               **envp,
+					GSpawnFlags           flags,
+					GSpawnChildSetupFunc  child_setup,
+					gpointer              user_data,
+					GPid                 *child_pid,
+					gint                 *standard_input,
+					gint                 *standard_output,
+					gint                 *standard_error,
+					gint                 *waitpid_status,
+					GError              **error);
 
 /* If standard_output or standard_error are non-NULL, the full
  * standard output or error of the command will be placed there.
