Distinguish more clearly between wait status and exit status

On Unix platforms, wait() and friends yield an integer that encodes
how the process exited. Confusingly, this is usually not the same as
the integer passed to exit() or returned from main(): conceptually it's
an integer encoding of this tagged union:

    enum { EXITED, SIGNALLED, ... } tag;
    union {
        int exit_status;         /* if EXITED */
        struct {
            int terminating_signal;
            bool core_dumped;
        } terminating_signal;    /* if SIGNALLED */
        ...
    } detail;

Meanwhile, on Windows, wait statuses and exit statuses are
interchangeable.

I find that it's clearer what is going on if we are consistent about
referring to the result of wait() as a "wait status", and the value
passed to exit() as an "exit status".

GSubprocess already gets this right: g_subprocess_get_status() returns
the wait status, while g_subprocess_get_exit_status() genuinely returns
the exit status. However, the GSpawn family of APIs has tended to
conflate the two.

Confusingly, g_spawn_check_exit_status() has always checked a wait
status, and it would not be correct to pass an exit status to it; so
let's deprecate it in favour of g_spawn_check_wait_status(), which
does the same thing that g_spawn_check_exit_status() always did.
Code that needs backwards-compatibility with older GLib can use:

    #if !GLIB_CHECK_VERSION(2, 69, 0)
    #define g_spawn_check_wait_status(x) (g_spawn_check_exit_status (x))
    #endif

Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie 2021-06-14 12:51:01 +01:00
parent f2be22ca52
commit e0b6b8037d
13 changed files with 159 additions and 105 deletions

View File

@ -1567,6 +1567,7 @@ g_spawn_async_with_pipes_and_fds
g_spawn_async
g_spawn_sync
G_SPAWN_EXIT_ERROR
g_spawn_check_wait_status
g_spawn_check_exit_status
g_spawn_command_line_async
g_spawn_command_line_sync

View File

@ -1082,7 +1082,7 @@ get_session_address_dbus_launch (GError **error)
gchar *command_line;
gchar *launch_stdout;
gchar *launch_stderr;
gint exit_status;
gint wait_status;
gchar *old_dbus_verbose;
gboolean restore_dbus_verbose;
@ -1146,13 +1146,13 @@ get_session_address_dbus_launch (GError **error)
if (!g_spawn_command_line_sync (command_line,
&launch_stdout,
&launch_stderr,
&exit_status,
&wait_status,
error))
{
goto out;
}
if (!g_spawn_check_exit_status (exit_status, error))
if (!g_spawn_check_wait_status (wait_status, error))
{
g_prefix_error (error, _("Error spawning command line “%s”: "), command_line);
goto out;

View File

@ -3734,7 +3734,7 @@ update_program_done (GPid pid,
gpointer data)
{
/* Did the application exit correctly */
if (g_spawn_check_exit_status (status, NULL))
if (g_spawn_check_wait_status (status, NULL))
{
/* Here we could clean out any caches in use */
}

View File

@ -883,7 +883,7 @@ g_subprocess_wait (GSubprocess *subprocess,
* @cancellable: a #GCancellable
* @error: a #GError
*
* Combines g_subprocess_wait() with g_spawn_check_exit_status().
* Combines g_subprocess_wait() with g_spawn_check_wait_status().
*
* Returns: %TRUE on success, %FALSE if process exited abnormally, or
* @cancellable was cancelled
@ -896,7 +896,7 @@ g_subprocess_wait_check (GSubprocess *subprocess,
GError **error)
{
return g_subprocess_wait (subprocess, cancellable, error) &&
g_spawn_check_exit_status (subprocess->status, error);
g_spawn_check_wait_status (subprocess->status, error);
}
/**
@ -906,7 +906,7 @@ g_subprocess_wait_check (GSubprocess *subprocess,
* @callback: a #GAsyncReadyCallback to call when the operation is complete
* @user_data: user_data for @callback
*
* Combines g_subprocess_wait_async() with g_spawn_check_exit_status().
* Combines g_subprocess_wait_async() with g_spawn_check_wait_status().
*
* This is the asynchronous version of g_subprocess_wait_check().
*
@ -940,7 +940,7 @@ g_subprocess_wait_check_finish (GSubprocess *subprocess,
GError **error)
{
return g_subprocess_wait_finish (subprocess, result, error) &&
g_spawn_check_exit_status (subprocess->status, error);
g_spawn_check_wait_status (subprocess->status, error);
}
#ifdef G_OS_UNIX
@ -1053,7 +1053,7 @@ g_subprocess_force_exit (GSubprocess *subprocess)
*
* This value has no particular meaning, but it can be used with the
* macros defined by the system headers such as WIFEXITED. It can also
* be used with g_spawn_check_exit_status().
* be used with g_spawn_check_wait_status().
*
* It is more likely that you want to use g_subprocess_get_if_exited()
* followed by g_subprocess_get_exit_status().

View File

@ -84,7 +84,7 @@ test_connection_flush (void)
for (n = 0; n < 50; n++)
{
gboolean ret;
gint exit_status;
gint wait_status;
guint timeout_mainloop_id;
gchar *flush_helper_stdout = NULL;
gchar *flush_helper_stderr = NULL;
@ -93,9 +93,9 @@ test_connection_flush (void)
ret = g_spawn_command_line_sync (flush_helper,
&flush_helper_stdout,
&flush_helper_stderr,
&exit_status,
&wait_status,
&error) &&
g_spawn_check_exit_status (exit_status, &error);
g_spawn_check_wait_status (wait_status, &error);
if (!ret)
g_test_message ("Child process %s failed. stdout:\n%s\nstderr:\n%s",
flush_helper, flush_helper_stdout, flush_helper_stderr);

View File

@ -611,7 +611,7 @@ on_subprocess_exited (GObject *object,
g_propagate_error (&data->error, error);
}
}
g_spawn_check_exit_status (g_subprocess_get_status (subprocess), &error);
g_spawn_check_wait_status (g_subprocess_get_status (subprocess), &error);
g_assert_no_error (error);
data->events_pending--;
if (data->events_pending == 0)
@ -1281,7 +1281,7 @@ on_request_quit_exited (GObject *object,
g_assert_true (g_subprocess_get_if_signaled (subprocess));
g_assert_cmpint (g_subprocess_get_term_sig (subprocess), ==, 9);
#endif
g_spawn_check_exit_status (g_subprocess_get_status (subprocess), &error);
g_spawn_check_wait_status (g_subprocess_get_status (subprocess), &error);
g_assert_nonnull (error);
g_clear_error (&error);

View File

@ -5730,7 +5730,7 @@ g_child_watch_source_new (GPid pid)
* you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to
* the spawn function for the child watching to work.
*
* In many programs, you will want to call g_spawn_check_exit_status()
* In many programs, you will want to call g_spawn_check_wait_status()
* in the callback to determine whether or not the child exited
* successfully.
*

View File

@ -193,16 +193,20 @@ typedef gboolean (*GSourceFunc) (gpointer user_data);
/**
* GChildWatchFunc:
* @pid: the process id of the child process
* @status: Status information about the child process, encoded
* in a platform-specific manner
* @wait_status: Status information about the child process, encoded
* in a platform-specific manner
* @user_data: user data passed to g_child_watch_add()
*
* Prototype of a #GChildWatchSource callback, called when a child
* process has exited. To interpret @status, see the documentation
* for g_spawn_check_exit_status().
* process has exited.
*
* To interpret @wait_status, see the documentation
* for g_spawn_check_wait_status(). In particular,
* on Unix platforms, note that it is usually not equal
* to the integer passed to `exit()` or returned from `main()`.
*/
typedef void (*GChildWatchFunc) (GPid pid,
gint status,
gint wait_status,
gpointer user_data);

View File

@ -949,7 +949,7 @@ g_spawn_sync (const gchar *working_directory,
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error)
{
gint outpipe = -1;
@ -1124,8 +1124,8 @@ g_spawn_sync (const gchar *working_directory,
/* No helper process, exit status of actual spawned process
* already available.
*/
if (exit_status)
*exit_status = status;
if (wait_status)
*wait_status = status;
}
else
{
@ -1141,8 +1141,8 @@ g_spawn_sync (const gchar *working_directory,
switch (helper_report[0])
{
case CHILD_NO_ERROR:
if (exit_status)
*exit_status = helper_report[1];
if (wait_status)
*wait_status = helper_report[1];
break;
default:
set_child_error (helper_report, working_directory, error);
@ -1332,7 +1332,7 @@ gboolean
g_spawn_command_line_sync (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error)
{
gboolean retval;
@ -1353,7 +1353,7 @@ g_spawn_command_line_sync (const gchar *command_line,
NULL,
standard_output,
standard_error,
exit_status,
wait_status,
error);
g_strfreev (argv);
@ -1394,16 +1394,18 @@ g_spawn_close_pid (GPid pid)
}
gboolean
g_spawn_check_exit_status (gint exit_status,
g_spawn_check_wait_status (gint wait_status,
GError **error)
{
gboolean ret = FALSE;
if (exit_status != 0)
if (wait_status != 0)
{
g_set_error (error, G_SPAWN_EXIT_ERROR, exit_status,
/* On Windows, the wait status is just the exit status: the
* difference between the two that exists on Unix is not relevant */
g_set_error (error, G_SPAWN_EXIT_ERROR, wait_status,
_("Child process exited with code %ld"),
(long) exit_status);
(long) wait_status);
goto out;
}
@ -1412,6 +1414,13 @@ g_spawn_check_exit_status (gint exit_status,
return ret;
}
gboolean
g_spawn_check_exit_status (gint wait_status,
GError **error)
{
return g_spawn_check_wait_status (wait_status, error);
}
#ifdef G_OS_WIN32
/* Binary compatibility versions. Not for newly compiled code. */
@ -1443,12 +1452,12 @@ _GLIB_EXTERN gboolean g_spawn_sync_utf8 (const gchar *wo
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error);
_GLIB_EXTERN gboolean g_spawn_command_line_sync_utf8 (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error);
_GLIB_EXTERN gboolean g_spawn_command_line_async_utf8 (const gchar *command_line,
GError **error);
@ -1508,7 +1517,7 @@ g_spawn_sync_utf8 (const gchar *working_directory,
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error)
{
return g_spawn_sync (working_directory,
@ -1519,7 +1528,7 @@ g_spawn_sync_utf8 (const gchar *working_directory,
user_data,
standard_output,
standard_error,
exit_status,
wait_status,
error);
}
@ -1527,13 +1536,13 @@ gboolean
g_spawn_command_line_sync_utf8 (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error)
{
return g_spawn_command_line_sync (command_line,
standard_output,
standard_error,
exit_status,
wait_status,
error);
}

View File

@ -141,7 +141,7 @@ extern char **environ;
* gpointer user_data)
* {
* g_message ("Child %" G_PID_FORMAT " exited %s", pid,
* g_spawn_check_exit_status (status, NULL) ? "normally" : "abnormally");
* g_spawn_check_wait_status (status, NULL) ? "normally" : "abnormally");
*
* // Free any resources associated with the child here, such as I/O channels
* // on its stdout and stderr FDs. If you have no code to put in the
@ -325,7 +325,7 @@ read_data (GString *str,
* @user_data: (closure): user data for @child_setup
* @standard_output: (out) (array zero-terminated=1) (element-type guint8) (optional): return location for child output, or %NULL
* @standard_error: (out) (array zero-terminated=1) (element-type guint8) (optional): return location for child error messages, or %NULL
* @exit_status: (out) (optional): return location for child exit status, as returned by waitpid(), or %NULL
* @wait_status: (out) (optional): return location for child wait status, as returned by waitpid(), or %NULL
* @error: return location for error, or %NULL
*
* Executes a child synchronously (waits for the child to exit before returning).
@ -334,15 +334,18 @@ read_data (GString *str,
* %G_SPAWN_STDOUT_TO_DEV_NULL and %G_SPAWN_STDERR_TO_DEV_NULL flags when
* passing %NULL for @standard_output and @standard_error.
*
* If @exit_status is non-%NULL, the platform-specific exit status of
* If @wait_status is non-%NULL, the platform-specific status of
* the child is stored there; see the documentation of
* g_spawn_check_exit_status() for how to use and interpret this.
* g_spawn_check_wait_status() for how to use and interpret this.
* On Unix platforms, note that it is usually not equal
* to the integer passed to `exit()` or returned from `main()`.
*
* Note that it is invalid to pass %G_SPAWN_DO_NOT_REAP_CHILD in
* @flags, and on POSIX platforms, the same restrictions as for
* g_child_watch_source_new() apply.
*
* If an error occurs, no data is returned in @standard_output,
* @standard_error, or @exit_status.
* @standard_error, or @wait_status.
*
* This function calls g_spawn_async_with_pipes() internally; see that
* function for full details on the other parameters and details on
@ -359,7 +362,7 @@ g_spawn_sync (const gchar *working_directory,
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error)
{
gint outpipe = -1;
@ -517,13 +520,13 @@ g_spawn_sync (const gchar *working_directory,
goto again;
else if (errno == ECHILD)
{
if (exit_status)
if (wait_status)
{
g_warning ("In call to g_spawn_sync(), exit status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes.");
g_warning ("In call to g_spawn_sync(), wait status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes.");
}
else
{
/* We don't need the exit status. */
/* We don't need the wait status. */
}
}
else
@ -554,8 +557,8 @@ g_spawn_sync (const gchar *working_directory,
}
else
{
if (exit_status)
*exit_status = status;
if (wait_status)
*wait_status = status;
if (standard_output)
*standard_output = g_string_free (outstr, FALSE);
@ -979,7 +982,7 @@ g_spawn_async_with_fds (const gchar *working_directory,
* @command_line: (type filename): a command line
* @standard_output: (out) (array zero-terminated=1) (element-type guint8) (optional): return location for child output
* @standard_error: (out) (array zero-terminated=1) (element-type guint8) (optional): return location for child errors
* @exit_status: (out) (optional): return location for child exit status, as returned by waitpid()
* @wait_status: (out) (optional): return location for child wait status, as returned by waitpid()
* @error: return location for errors
*
* A simple version of g_spawn_sync() with little-used parameters
@ -991,9 +994,11 @@ g_spawn_async_with_fds (const gchar *working_directory,
* appropriate. Possible errors are those from g_spawn_sync() and those
* from g_shell_parse_argv().
*
* If @exit_status is non-%NULL, the platform-specific exit status of
* If @wait_status is non-%NULL, the platform-specific status of
* the child is stored there; see the documentation of
* g_spawn_check_exit_status() for how to use and interpret this.
* g_spawn_check_wait_status() for how to use and interpret this.
* On Unix platforms, note that it is usually not equal
* to the integer passed to `exit()` or returned from `main()`.
*
* On Windows, please note the implications of g_shell_parse_argv()
* parsing @command_line. Parsing is done according to Unix shell rules, not
@ -1011,7 +1016,7 @@ gboolean
g_spawn_command_line_sync (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error)
{
gboolean retval;
@ -1032,7 +1037,7 @@ g_spawn_command_line_sync (const gchar *command_line,
NULL,
standard_output,
standard_error,
exit_status,
wait_status,
error);
g_strfreev (argv);
@ -1084,32 +1089,32 @@ g_spawn_command_line_async (const gchar *command_line,
}
/**
* g_spawn_check_exit_status:
* @exit_status: An exit code as returned from g_spawn_sync()
* g_spawn_check_wait_status:
* @wait_status: A platform-specific wait status as returned from g_spawn_sync()
* @error: a #GError
*
* Set @error if @exit_status indicates the child exited abnormally
* Set @error if @wait_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.
* The g_spawn_sync() and g_child_watch_add() family of APIs return the
* status of subprocesses encoded in a platform-specific way.
* On Unix, this is guaranteed to be in the same format waitpid() returns,
* and on Windows it is guaranteed to be the result of GetExitCodeProcess().
*
* Prior to the introduction of this function in GLib 2.34, interpreting
* @exit_status required use of platform-specific APIs, which is problematic
* @wait_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.
* human-readable information about the wait status.
*
* The @domain and @code 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 WIFEXITED() would be true of
* @exit_status. On Windows, it is always the case.
* @wait_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.
@ -1121,43 +1126,46 @@ g_spawn_command_line_async (const gchar *command_line,
*
* This function just offers convenience; you can of course also check
* the available platform via a macro such as %G_OS_UNIX, and use
* WIFEXITED() and WEXITSTATUS() on @exit_status directly. Do not attempt
* WIFEXITED() and WEXITSTATUS() on @wait_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.
*
* Prior to version 2.70, g_spawn_check_exit_status() provides the same
* functionality, although under a misleading name.
*
* Returns: %TRUE if child exited successfully, %FALSE otherwise (and
* @error will be set)
*
* Since: 2.34
* Since: 2.70
*/
gboolean
g_spawn_check_exit_status (gint exit_status,
g_spawn_check_wait_status (gint wait_status,
GError **error)
{
gboolean ret = FALSE;
if (WIFEXITED (exit_status))
if (WIFEXITED (wait_status))
{
if (WEXITSTATUS (exit_status) != 0)
if (WEXITSTATUS (wait_status) != 0)
{
g_set_error (error, G_SPAWN_EXIT_ERROR, WEXITSTATUS (exit_status),
g_set_error (error, G_SPAWN_EXIT_ERROR, WEXITSTATUS (wait_status),
_("Child process exited with code %ld"),
(long) WEXITSTATUS (exit_status));
(long) WEXITSTATUS (wait_status));
goto out;
}
}
else if (WIFSIGNALED (exit_status))
else if (WIFSIGNALED (wait_status))
{
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
_("Child process killed by signal %ld"),
(long) WTERMSIG (exit_status));
(long) WTERMSIG (wait_status));
goto out;
}
else if (WIFSTOPPED (exit_status))
else if (WIFSTOPPED (wait_status))
{
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
_("Child process stopped by signal %ld"),
(long) WSTOPSIG (exit_status));
(long) WSTOPSIG (wait_status));
goto out;
}
else
@ -1172,6 +1180,34 @@ g_spawn_check_exit_status (gint exit_status,
return ret;
}
/**
* g_spawn_check_exit_status:
* @wait_status: A status as returned from g_spawn_sync()
* @error: a #GError
*
* An old name for g_spawn_check_wait_status(), deprecated because its
* name is misleading.
*
* Despite the name of the function, @wait_status must be the wait status
* as returned by g_spawn_sync(), g_subprocess_get_status(), `waitpid()`,
* etc. On Unix platforms, it is incorrect for it to be the exit status
* as passed to `exit()` or returned by g_subprocess_get_exit_status() or
* `WEXITSTATUS()`.
*
* Returns: %TRUE if child exited successfully, %FALSE otherwise (and
* @error will be set)
*
* Since: 2.34
*
* Deprecated: 2.70: Use g_spawn_check_wait_status() instead, and check whether your code is conflating wait and exit statuses.
*/
gboolean
g_spawn_check_exit_status (gint wait_status,
GError **error)
{
return g_spawn_check_wait_status (wait_status, error);
}
/* This function is called between fork() and exec() and hence must be
* async-signal-safe (see signal-safety(7)). */
static gssize

View File

@ -95,7 +95,7 @@ typedef enum
/**
* G_SPAWN_EXIT_ERROR:
*
* Error domain used by g_spawn_check_exit_status(). The code
* Error domain used by g_spawn_check_wait_status(). The code
* will be the program exit code.
*/
#define G_SPAWN_EXIT_ERROR g_spawn_exit_error_quark ()
@ -259,21 +259,25 @@ gboolean g_spawn_sync (const gchar *working_directory,
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error);
GLIB_AVAILABLE_IN_ALL
gboolean g_spawn_command_line_sync (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
gint *exit_status,
gint *wait_status,
GError **error);
GLIB_AVAILABLE_IN_ALL
gboolean g_spawn_command_line_async (const gchar *command_line,
GError **error);
GLIB_AVAILABLE_IN_2_34
gboolean g_spawn_check_exit_status (gint exit_status,
GLIB_AVAILABLE_IN_2_70
gboolean g_spawn_check_wait_status (gint wait_status,
GError **error);
GLIB_DEPRECATED_IN_2_70_FOR(g_spawn_check_wait_status)
gboolean g_spawn_check_exit_status (gint wait_status,
GError **error);
GLIB_AVAILABLE_IN_ALL

View File

@ -408,17 +408,17 @@ test_spawn_nonexistent (void)
GError *error = NULL;
GPtrArray *argv = NULL;
gchar *stdout_str = NULL;
gint exit_status = -1;
gint wait_status = -1;
argv = g_ptr_array_new ();
g_ptr_array_add (argv, "this does not exist");
g_ptr_array_add (argv, NULL);
g_spawn_sync (NULL, (char**) argv->pdata, NULL, 0, NULL, NULL, &stdout_str,
NULL, &exit_status, &error);
NULL, &wait_status, &error);
g_assert_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT);
g_assert_null (stdout_str);
g_assert_cmpint (exit_status, ==, -1);
g_assert_cmpint (wait_status, ==, -1);
g_ptr_array_free (argv, TRUE);

View File

@ -878,7 +878,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 77);
g_clear_error (&error);
@ -900,7 +900,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 77);
g_clear_error (&error);
@ -918,7 +918,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 77);
g_clear_error (&error);
@ -940,7 +940,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_test_message ("one pass and some incomplete -> overall status 0");
@ -959,7 +959,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_test_message ("one pass and mix of skipped and incomplete -> overall status 0");
@ -980,7 +980,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_test_message ("one fail and some skipped -> overall status fail");
@ -1001,7 +1001,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_clear_error (&error);
@ -1021,7 +1021,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_clear_error (&error);
@ -1043,7 +1043,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_clear_error (&error);
@ -1075,7 +1075,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_assert_nonnull (strstr (output, "\nok 1 /pass\n"));
g_free (output);
@ -1094,7 +1094,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_assert_nonnull (strstr (output, "\nok 1 /skip # SKIP not enough tea\n"));
g_free (output);
@ -1113,7 +1113,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_assert_nonnull (strstr (output, "\nnot ok 1 /incomplete # TODO mind reading not implemented yet\n"));
g_free (output);
@ -1132,7 +1132,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_assert_nonnull (strstr (output, "\nnot ok 1 /fail\n"));
g_free (output);
@ -1166,7 +1166,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_ptr_array_unref (argv);
@ -1197,7 +1197,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a\n"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@ -1229,7 +1229,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a\n"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@ -1261,7 +1261,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP\n"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a # SKIP\n"));
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@ -1292,7 +1292,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 5 /b/b\n"));
g_assert_nonnull (strstr (output, "\n1..5\n"));
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@ -1324,7 +1324,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 6 /b/b/a\n"));
g_assert_nonnull (strstr (output, "\n1..6\n"));
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@ -1350,7 +1350,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 2 /b/b/a\n"));
g_assert_nonnull (strstr (output, "\n1..2\n"));
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@ -1374,7 +1374,7 @@ test_tap (void)
NULL, NULL, &output, NULL, &status,
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_nonnull (error);
g_assert_nonnull (strstr (output, "do not mix [-r | --run-prefix] with '-p'\n"));
g_clear_error (&error);
@ -1416,7 +1416,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP by request"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@ -1453,7 +1453,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP by request"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@ -1477,7 +1477,7 @@ test_tap (void)
NULL, NULL, &output, NULL, &status,
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_nonnull (error);
g_assert_nonnull (strstr (output, "do not mix [-x | --skip-prefix] with '-s'\n"));
g_clear_error (&error);
@ -1511,7 +1511,7 @@ test_tap_summary (void)
&error);
g_assert_no_error (error);
g_spawn_check_exit_status (status, &error);
g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
/* Note: The test path in the output is not `/tap/summary` because its the
* test path from testing-helper, not from this function. */