mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 08:22:16 +01:00 
			
		
		
		
	Add g_spawn_check_exit_status()
Many (if not "almost all") programs that spawn other programs via g_spawn_sync() or the like simply want to check whether or not the child exited successfully, but doing so requires use of platform-specific functionality and there's actually a fair amount of boilerplate involved. This new API will help drain a *lot* of mostly duplicated code in GNOME, from gnome-session to gdm. And we can see that some bits even inside GLib were doing it wrong; for example checking the exit status on Unix, but ignoring it on Windows. https://bugzilla.gnome.org/show_bug.cgi?id=679691
This commit is contained in:
		| @@ -1093,6 +1093,7 @@ GSpawnChildSetupFunc | |||||||
| g_spawn_async_with_pipes | g_spawn_async_with_pipes | ||||||
| g_spawn_async | g_spawn_async | ||||||
| g_spawn_sync | g_spawn_sync | ||||||
|  | g_spawn_check_exit_status | ||||||
| g_spawn_command_line_async | g_spawn_command_line_async | ||||||
| g_spawn_command_line_sync | g_spawn_command_line_sync | ||||||
| g_spawn_close_pid | g_spawn_close_pid | ||||||
|   | |||||||
| @@ -43,7 +43,6 @@ | |||||||
|  |  | ||||||
| #ifdef G_OS_UNIX | #ifdef G_OS_UNIX | ||||||
| #include <gio/gunixsocketaddress.h> | #include <gio/gunixsocketaddress.h> | ||||||
| #include <sys/wait.h> |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifdef G_OS_WIN32 | #ifdef G_OS_WIN32 | ||||||
| @@ -1062,40 +1061,16 @@ get_session_address_dbus_launch (GError **error) | |||||||
|                                   &launch_stderr, |                                   &launch_stderr, | ||||||
|                                   &exit_status, |                                   &exit_status, | ||||||
|                                   error)) |                                   error)) | ||||||
|  |     { | ||||||
|  |       goto out; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (!g_spawn_check_exit_status (exit_status, error)) | ||||||
|     { |     { | ||||||
|       g_prefix_error (error, _("Error spawning command line `%s': "), command_line); |       g_prefix_error (error, _("Error spawning command line `%s': "), command_line); | ||||||
|       goto out; |       goto out; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if (!WIFEXITED (exit_status)) |  | ||||||
|     { |  | ||||||
|       gchar *escaped_stderr; |  | ||||||
|       escaped_stderr = g_strescape (launch_stderr, ""); |  | ||||||
|       g_set_error (error, |  | ||||||
|                    G_IO_ERROR, |  | ||||||
|                    G_IO_ERROR_FAILED, |  | ||||||
|                    _("Abnormal program termination spawning command line `%s': %s"), |  | ||||||
|                    command_line, |  | ||||||
|                    escaped_stderr); |  | ||||||
|       g_free (escaped_stderr); |  | ||||||
|       goto out; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   if (WEXITSTATUS (exit_status) != 0) |  | ||||||
|     { |  | ||||||
|       gchar *escaped_stderr; |  | ||||||
|       escaped_stderr = g_strescape (launch_stderr, ""); |  | ||||||
|       g_set_error (error, |  | ||||||
|                    G_IO_ERROR, |  | ||||||
|                    G_IO_ERROR_FAILED, |  | ||||||
|                    _("Command line `%s' exited with non-zero exit status %d: %s"), |  | ||||||
|                    command_line, |  | ||||||
|                    WEXITSTATUS (exit_status), |  | ||||||
|                    escaped_stderr); |  | ||||||
|       g_free (escaped_stderr); |  | ||||||
|       goto out; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   /* From the dbus-launch(1) man page: |   /* From the dbus-launch(1) man page: | ||||||
|    * |    * | ||||||
|    *   --binary-syntax Write to stdout a nul-terminated bus address, |    *   --binary-syntax Write to stdout a nul-terminated bus address, | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ | |||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <sys/wait.h> |  | ||||||
|  |  | ||||||
| #ifdef HAVE_CRT_EXTERNS_H | #ifdef HAVE_CRT_EXTERNS_H | ||||||
| #include <crt_externs.h> | #include <crt_externs.h> | ||||||
| @@ -1850,8 +1849,7 @@ update_program_done (GPid     pid, | |||||||
| 		     gpointer data) | 		     gpointer data) | ||||||
| { | { | ||||||
|   /* Did the application exit correctly */ |   /* Did the application exit correctly */ | ||||||
|   if (WIFEXITED (status) && |   if (g_spawn_check_exit_status (status, NULL)) | ||||||
|       WEXITSTATUS (status) == 0) |  | ||||||
|     { |     { | ||||||
|       /* Here we could clean out any caches in use */ |       /* Here we could clean out any caches in use */ | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -33,9 +33,6 @@ | |||||||
| #ifdef G_OS_WIN32 | #ifdef G_OS_WIN32 | ||||||
| #include <io.h> | #include <io.h> | ||||||
| #endif | #endif | ||||||
| #ifdef HAVE_SYS_WAIT_H |  | ||||||
| #include <sys/wait.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <gio/gmemoryoutputstream.h> | #include <gio/gmemoryoutputstream.h> | ||||||
| #include <gio/gzlibcompressor.h> | #include <gio/gzlibcompressor.h> | ||||||
| @@ -331,14 +328,14 @@ end_element (GMarkupParseContext  *context, | |||||||
|                   g_propagate_error (error, my_error); |                   g_propagate_error (error, my_error); | ||||||
|                   goto cleanup; |                   goto cleanup; | ||||||
|                 } |                 } | ||||||
| #ifdef HAVE_SYS_WAIT_H | 	       | ||||||
|               if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) | 	      /* Ugly...we shoud probably just let stderr be inherited */ | ||||||
|  | 	      if (!g_spawn_check_exit_status (status, NULL)) | ||||||
|                 { |                 { | ||||||
|                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, |                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, | ||||||
|                                _("Error processing input file with xmllint:\n%s"), stderr_child); |                                _("Error processing input file with xmllint:\n%s"), stderr_child); | ||||||
|                   goto cleanup; |                   goto cleanup; | ||||||
|                 } |                 } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|               g_free (stderr_child); |               g_free (stderr_child); | ||||||
|               g_free (real_file); |               g_free (real_file); | ||||||
| @@ -387,14 +384,13 @@ end_element (GMarkupParseContext  *context, | |||||||
|                   g_propagate_error (error, my_error); |                   g_propagate_error (error, my_error); | ||||||
|                   goto cleanup; |                   goto cleanup; | ||||||
|                 } |                 } | ||||||
| #ifdef HAVE_SYS_WAIT_H | 	       | ||||||
|               if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) | 	      if (!g_spawn_check_exit_status (status, NULL)) | ||||||
|                 { |                 { | ||||||
|                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, |                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, | ||||||
| 			       _("Error processing input file with to-pixdata:\n%s"), stderr_child); | 			       _("Error processing input file with to-pixdata:\n%s"), stderr_child); | ||||||
|                   goto cleanup; |                   goto cleanup; | ||||||
|                 } |                 } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|               g_free (stderr_child); |               g_free (stderr_child); | ||||||
|               g_free (real_file); |               g_free (real_file); | ||||||
|   | |||||||
| @@ -25,9 +25,6 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #ifdef HAVE_SYS_WAIT_H |  | ||||||
| #include <sys/wait.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include "gdbus-tests.h" | #include "gdbus-tests.h" | ||||||
|  |  | ||||||
| @@ -97,10 +94,8 @@ test_connection_flush (void) | |||||||
|                                        &exit_status, |                                        &exit_status, | ||||||
|                                        &error); |                                        &error); | ||||||
|       g_assert_no_error (error); |       g_assert_no_error (error); | ||||||
| #ifdef HAVE_SYS_WAIT_H |       g_spawn_check_exit_status (exit_status, &error); | ||||||
|       g_assert (WIFEXITED (exit_status)); |       g_assert_no_error (error); | ||||||
|       g_assert_cmpint (WEXITSTATUS (exit_status), ==, 0); |  | ||||||
| #endif |  | ||||||
|       g_assert (ret); |       g_assert (ret); | ||||||
|  |  | ||||||
|       timeout_mainloop_id = g_timeout_add (1000, test_connection_flush_on_timeout, GUINT_TO_POINTER (n)); |       timeout_mainloop_id = g_timeout_add (1000, test_connection_flush_on_timeout, GUINT_TO_POINTER (n)); | ||||||
|   | |||||||
| @@ -141,7 +141,7 @@ test_connection_life_cycle (void) | |||||||
|    * |    * | ||||||
|    */ |    */ | ||||||
|   c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); |   c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); | ||||||
|   _g_assert_error_domain (error, G_IO_ERROR); |   g_assert (error != NULL); | ||||||
|   g_assert (!g_dbus_error_is_remote_error (error)); |   g_assert (!g_dbus_error_is_remote_error (error)); | ||||||
|   g_assert (c == NULL); |   g_assert (c == NULL); | ||||||
|   g_error_free (error); |   g_error_free (error); | ||||||
|   | |||||||
| @@ -980,6 +980,7 @@ g_spawn_command_line_async PRIVATE | |||||||
| g_spawn_command_line_sync PRIVATE | g_spawn_command_line_sync PRIVATE | ||||||
| #endif | #endif | ||||||
| g_spawn_error_quark | g_spawn_error_quark | ||||||
|  | g_spawn_exit_error_quark | ||||||
| #ifndef _WIN64 | #ifndef _WIN64 | ||||||
| g_spawn_sync PRIVATE | g_spawn_sync PRIVATE | ||||||
| #endif | #endif | ||||||
| @@ -990,6 +991,7 @@ g_spawn_command_line_async_utf8 | |||||||
| g_spawn_command_line_sync_utf8 | g_spawn_command_line_sync_utf8 | ||||||
| g_spawn_sync_utf8 | g_spawn_sync_utf8 | ||||||
| #endif | #endif | ||||||
|  | g_spawn_check_exit_status | ||||||
| #if !defined(G_OS_UNIX) || defined(G_STDIO_NO_WRAP_ON_UNIX) | #if !defined(G_OS_UNIX) || defined(G_STDIO_NO_WRAP_ON_UNIX) | ||||||
| /* gstdio wrappers */ | /* gstdio wrappers */ | ||||||
| g_chmod | g_chmod | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								glib/gmain.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								glib/gmain.c
									
									
									
									
									
								
							| @@ -4665,10 +4665,14 @@ g_child_watch_source_new (GPid pid) | |||||||
|  * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to  |  * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to  | ||||||
|  * the spawn function for the child watching to work. |  * the spawn function for the child watching to work. | ||||||
|  * |  * | ||||||
|  * Note that on platforms where #GPid must be explicitly closed |  * In many programs, you will want to call g_spawn_check_exit_status() | ||||||
|  * (see g_spawn_close_pid()) @pid must not be closed while the |  * in the callback to determine whether or not the child exited | ||||||
|  * source is still active. Typically, you will want to call |  * successfully. | ||||||
|  * g_spawn_close_pid() in the callback function for the source. |  *  | ||||||
|  |  * Also, note that on platforms where #GPid must be explicitly closed | ||||||
|  |  * (see g_spawn_close_pid()) @pid must not be closed while the source | ||||||
|  |  * is still active.  Typically, you should invoke g_spawn_close_pid() | ||||||
|  |  * in the callback function for the source. | ||||||
|  *  |  *  | ||||||
|  * GLib supports only a single callback per process id. |  * GLib supports only a single callback per process id. | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -139,11 +139,13 @@ typedef gboolean (*GSourceFunc)       (gpointer user_data); | |||||||
| /** | /** | ||||||
|  * GChildWatchFunc: |  * GChildWatchFunc: | ||||||
|  * @pid: the process id of the child process |  * @pid: the process id of the child process | ||||||
|  * @status: Status information about the child process, |  * @status: Status information about the child process, encoded | ||||||
|  *     see waitpid(2) for more information about this field |  *     in a platform-specific manner | ||||||
|  * @user_data: user data passed to g_child_watch_add() |  * @user_data: user data passed to g_child_watch_add() | ||||||
|  * |  * | ||||||
|  * The type of functions to be called when a child exists. |  * Prototype of a #GChildWatchSource callback, called when a child | ||||||
|  |  * process has exited.  To interpret @status, see the documentation | ||||||
|  |  * for g_spawn_check_exit_status(). | ||||||
|  */ |  */ | ||||||
| typedef void     (*GChildWatchFunc)   (GPid     pid, | typedef void     (*GChildWatchFunc)   (GPid     pid, | ||||||
|                                        gint     status, |                                        gint     status, | ||||||
|   | |||||||
							
								
								
									
										124
									
								
								glib/gspawn.c
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								glib/gspawn.c
									
									
									
									
									
								
							| @@ -94,6 +94,12 @@ g_spawn_error_quark (void) | |||||||
|   return g_quark_from_static_string ("g-exec-error-quark"); |   return g_quark_from_static_string ("g-exec-error-quark"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | GQuark | ||||||
|  | g_spawn_exit_error_quark (void) | ||||||
|  | { | ||||||
|  |   return g_quark_from_static_string ("g-spawn-exit-error-quark"); | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * g_spawn_async: |  * g_spawn_async: | ||||||
|  * @working_directory: (allow-none): child's current working directory, or %NULL to inherit parent's |  * @working_directory: (allow-none): child's current working directory, or %NULL to inherit parent's | ||||||
| @@ -232,11 +238,13 @@ read_data (GString *str, | |||||||
|  * if those parameters are non-%NULL. Note that you must set the   |  * if those parameters are non-%NULL. Note that you must set the   | ||||||
|  * %G_SPAWN_STDOUT_TO_DEV_NULL and %G_SPAWN_STDERR_TO_DEV_NULL flags when |  * %G_SPAWN_STDOUT_TO_DEV_NULL and %G_SPAWN_STDERR_TO_DEV_NULL flags when | ||||||
|  * passing %NULL for @standard_output and @standard_error. |  * passing %NULL for @standard_output and @standard_error. | ||||||
|  * If @exit_status is non-%NULL, the exit status of the child is stored |  * | ||||||
|  * there as it would be returned by waitpid(); standard UNIX macros such  |  * If @exit_status is non-%NULL, the platform-specific exit status of | ||||||
|  * as WIFEXITED() and WEXITSTATUS() must be used to evaluate the exit status. |  * the child is stored there; see the doucumentation of | ||||||
|  * Note that this function call waitpid() even if @exit_status is %NULL, and |  * g_spawn_check_exit_status() for how to use and interpret this. | ||||||
|  * does not accept the %G_SPAWN_DO_NOT_REAP_CHILD flag. |  * Note that it is invalid to pass %G_SPAWN_DO_NOT_REAP_CHILD in | ||||||
|  |  * @flags. | ||||||
|  |  * | ||||||
|  * If an error occurs, no data is returned in @standard_output, |  * If an error occurs, no data is returned in @standard_output, | ||||||
|  * @standard_error, or @exit_status. |  * @standard_error, or @exit_status. | ||||||
|  * |  * | ||||||
| @@ -701,9 +709,9 @@ g_spawn_async_with_pipes (const gchar          *working_directory, | |||||||
|  * appropriate. Possible errors are those from g_spawn_sync() and those |  * appropriate. Possible errors are those from g_spawn_sync() and those | ||||||
|  * from g_shell_parse_argv(). |  * from g_shell_parse_argv(). | ||||||
|  * |  * | ||||||
|  * If @exit_status is non-%NULL, the exit status of the child is stored there as |  * If @exit_status is non-%NULL, the platform-specific exit status of | ||||||
|  * it would be returned by waitpid(); standard UNIX macros such as WIFEXITED() |  * the child is stored there; see the documentation of | ||||||
|  * and WEXITSTATUS() must be used to evaluate the exit status. |  * g_spawn_check_exit_status() for how to use and interpret this. | ||||||
|  *  |  *  | ||||||
|  * On Windows, please note the implications of g_shell_parse_argv() |  * On Windows, please note the implications of g_shell_parse_argv() | ||||||
|  * parsing @command_line. Parsing is done according to Unix shell rules, not  |  * parsing @command_line. Parsing is done according to Unix shell rules, not  | ||||||
| @@ -793,6 +801,106 @@ g_spawn_command_line_async (const gchar *command_line, | |||||||
|   return retval; |   return retval; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * g_spawn_check_exit_status: | ||||||
|  |  * @exit_status: An exit code as returned from g_spawn_sync() | ||||||
|  |  * @error: a #GError | ||||||
|  |  * | ||||||
|  |  * Set @error if @exit_status indicates the child exited abnormally | ||||||
|  |  * (e.g. with a nonzero exit code, or via a fatal signal). | ||||||
|  |  * | ||||||
|  |  * The g_spawn_sync() and g_child_watch_add() family of APIs return an | ||||||
|  |  * exit status for subprocesses encoded in a platform-specific way. | ||||||
|  |  * On Unix, this is guaranteed to be in the same format | ||||||
|  |  * <literal>waitpid(2)</literal> returns, and on Windows it is | ||||||
|  |  * guaranteed to be the result of | ||||||
|  |  * <literal>GetExitCodeProcess()</literal>.  Prior to the introduction | ||||||
|  |  * of this function in GLib 2.34, interpreting @exit_status required | ||||||
|  |  * use of platform-specific APIs, which is problematic for software | ||||||
|  |  * using GLib as a cross-platform layer. | ||||||
|  |  * | ||||||
|  |  * Additionally, many programs simply want to determine whether or not | ||||||
|  |  * the child exited successfully, and either propagate a #GError or | ||||||
|  |  * print a message to standard error.  In that common case, this | ||||||
|  |  * function can be used.  Note that the error message in @error will | ||||||
|  |  * contain human-readable information about the exit status. | ||||||
|  |  * | ||||||
|  |  * The <literal>domain</literal> and <literal>code</literal> of @error | ||||||
|  |  * have special semantics in the case where the process has an "exit | ||||||
|  |  * code", as opposed to being killed by a signal.  On Unix, this | ||||||
|  |  * happens if <literal>WIFEXITED</literal> would be true of | ||||||
|  |  * @exit_status.  On Windows, it is always the case. | ||||||
|  |  * | ||||||
|  |  * The special semantics are that the actual exit code will be the | ||||||
|  |  * code set in @error, and the domain will be %G_SPAWN_EXIT_ERROR. | ||||||
|  |  * This allows you to differentiate between different exit codes. | ||||||
|  |  * | ||||||
|  |  * If the process was terminated by some means other than an exit | ||||||
|  |  * status, the domain will be %G_SPAWN_ERROR, and the code will be | ||||||
|  |  * %G_SPAWN_ERROR_FAILED. | ||||||
|  |  * | ||||||
|  |  * This function just offers convenience; you can of course also check | ||||||
|  |  * the available platform via a macro such as %G_OS_UNIX, and use | ||||||
|  |  * <literal>WIFEXITED()</literal> and <literal>WEXITSTATUS()</literal> | ||||||
|  |  * on @exit_status directly.  Do not attempt to scan or parse the | ||||||
|  |  * error message string; it may be translated and/or change in future | ||||||
|  |  * versions of GLib. | ||||||
|  |  * | ||||||
|  |  * Returns: %TRUE if child exited successfully, %FALSE otherwise (and @error will be set) | ||||||
|  |  * Since: 2.34 | ||||||
|  |  */ | ||||||
|  | gboolean | ||||||
|  | g_spawn_check_exit_status (gint      exit_status, | ||||||
|  | 			   GError  **error) | ||||||
|  | { | ||||||
|  |   gboolean ret = FALSE; | ||||||
|  |  | ||||||
|  | #ifdef G_OS_UNIX | ||||||
|  |   if (WIFEXITED (exit_status)) | ||||||
|  |     { | ||||||
|  |       if (WEXITSTATUS (exit_status) != 0) | ||||||
|  | 	{ | ||||||
|  | 	  g_set_error (error, G_SPAWN_EXIT_ERROR, WEXITSTATUS (exit_status), | ||||||
|  | 		       _("Child process exited with code %ld"), | ||||||
|  | 		       (long) WEXITSTATUS (exit_status)); | ||||||
|  | 	  goto out; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |   else if (WIFSIGNALED (exit_status)) | ||||||
|  |     { | ||||||
|  |       g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, | ||||||
|  | 		   _("Child process killed by signal %ld"), | ||||||
|  | 		   (long) WTERMSIG (exit_status)); | ||||||
|  |       goto out; | ||||||
|  |     } | ||||||
|  |   else if (WIFSTOPPED (exit_status)) | ||||||
|  |     { | ||||||
|  |       g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, | ||||||
|  | 		   _("Child process stopped by signal %ld"), | ||||||
|  | 		   (long) WSTOPSIG (exit_status)); | ||||||
|  |       goto out; | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, | ||||||
|  | 		   _("Child process exited abnormally")); | ||||||
|  |       goto out; | ||||||
|  |     } | ||||||
|  | #else | ||||||
|  |   if (exit_status != 0) | ||||||
|  |     { | ||||||
|  |       g_set_error (error, G_SPAWN_EXIT_ERROR, exit_status, | ||||||
|  | 		   _("Child process exited with code %ld"), | ||||||
|  | 		   (long) exit_status); | ||||||
|  |       goto out; | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   ret = TRUE; | ||||||
|  |  out: | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
| static gint | static gint | ||||||
| exec_err_to_g_error (gint en) | exec_err_to_g_error (gint en) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -96,6 +96,14 @@ typedef enum | |||||||
|                               */ |                               */ | ||||||
| } GSpawnError; | } GSpawnError; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * G_SPAWN_EXIT_ERROR: | ||||||
|  |  * | ||||||
|  |  * Error domain used by g_spawn_check_exit_status().  The code | ||||||
|  |  * will be the the program exit code. | ||||||
|  |  */ | ||||||
|  | #define G_SPAWN_EXIT_ERROR g_spawn_exit_error_quark () | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * GSpawnChildSetupFunc: |  * GSpawnChildSetupFunc: | ||||||
|  * @user_data: user data to pass to the function. |  * @user_data: user data to pass to the function. | ||||||
| @@ -176,6 +184,7 @@ typedef enum | |||||||
| } GSpawnFlags; | } GSpawnFlags; | ||||||
|  |  | ||||||
| GQuark g_spawn_error_quark (void); | GQuark g_spawn_error_quark (void); | ||||||
|  | GQuark g_spawn_exit_error_quark (void); | ||||||
|  |  | ||||||
| #ifndef __GTK_DOC_IGNORE__ | #ifndef __GTK_DOC_IGNORE__ | ||||||
| #ifdef G_OS_WIN32 | #ifdef G_OS_WIN32 | ||||||
| @@ -236,6 +245,10 @@ gboolean g_spawn_command_line_sync  (const gchar          *command_line, | |||||||
| gboolean g_spawn_command_line_async (const gchar          *command_line, | gboolean g_spawn_command_line_async (const gchar          *command_line, | ||||||
|                                      GError              **error); |                                      GError              **error); | ||||||
|  |  | ||||||
|  | GLIB_AVAILABLE_IN_2_34 | ||||||
|  | gboolean g_spawn_check_exit_status (gint      exit_status, | ||||||
|  | 				    GError  **error); | ||||||
|  |  | ||||||
| void g_spawn_close_pid (GPid pid); | void g_spawn_close_pid (GPid pid); | ||||||
|  |  | ||||||
| G_END_DECLS | G_END_DECLS | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user