mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 07:26:15 +01:00
g_child_watch_source_new: Document restrictions for POSIX platforms
The warnings issued when dealing with waitpid() raising ECHILD are somewhat misleading: there are lots of reasons why waitpid() might fail in this way, and we can't tell which one has happened. In particular, passing a non-child or a non-pid, waiting for the same pid elsewhere, or creating a duplicate watch for the same pid would all fail in the same way. Consolidate the restrictions into one place, and change all the other places they were (or should have been!) mentioned to point to that one place. Signed-off-by: Simon McVittie <smcv@collabora.com> Reviewed-by: Philip Withnall <withnall@endlessm.com> Bug: https://bugzilla.gnome.org/show_bug.cgi?id=723743
This commit is contained in:
parent
65e443da65
commit
6e480634c6
30
glib/gmain.c
30
glib/gmain.c
@ -5080,7 +5080,7 @@ dispatch_unix_signals_unlocked (void)
|
||||
}
|
||||
else if (pid == -1 && errno == ECHILD)
|
||||
{
|
||||
g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). Most likely the process is ignoring SIGCHLD, or some other thread is invoking waitpid() with a nonpositive first argument; either behavior can break applications that use g_child_watch_add()/g_spawn_sync() either directly or indirectly.");
|
||||
g_warning ("GChildWatchSource: 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.");
|
||||
source->child_exited = TRUE;
|
||||
source->child_status = 0;
|
||||
wake_source ((GSource *) source);
|
||||
@ -5321,14 +5321,24 @@ g_unix_signal_handler (int signum)
|
||||
* source is still active. Typically, you will want to call
|
||||
* g_spawn_close_pid() in the callback function for the source.
|
||||
*
|
||||
* Note further that using g_child_watch_source_new() is not
|
||||
* compatible with calling `waitpid` with a nonpositive first
|
||||
* argument in the application. Calling waitpid() for individual
|
||||
* pids will still work fine.
|
||||
* On POSIX platforms, the following restrictions apply to this API
|
||||
* due to limitations in POSIX process interfaces:
|
||||
*
|
||||
* Similarly, on POSIX platforms, the @pid passed to this function must
|
||||
* be greater than 0 (i.e. this function must wait for a specific child,
|
||||
* and cannot wait for one of many children by using a nonpositive argument).
|
||||
* * @pid must be a child of this process
|
||||
* * @pid must be positive
|
||||
* * the application must not call `waitpid` with a non-positive
|
||||
* first argument, for instance in another thread
|
||||
* * the application must not wait for @pid to exit by any other
|
||||
* mechanism, including `waitpid(pid, ...)` or a second child-watch
|
||||
* source for the same @pid
|
||||
* * the application must not ignore SIGCHILD
|
||||
*
|
||||
* If any of those conditions are not met, this and related APIs will
|
||||
* not work correctly. This can often be diagnosed via a GLib warning
|
||||
* stating that `ECHILD` was received by `waitpid`.
|
||||
*
|
||||
* Calling `waitpid` for specific processes other than @pid remains a
|
||||
* valid thing to do.
|
||||
*
|
||||
* Returns: the newly-created child watch source
|
||||
*
|
||||
@ -5393,6 +5403,8 @@ g_child_watch_source_new (GPid pid)
|
||||
* in the callback function for the source.
|
||||
*
|
||||
* GLib supports only a single callback per process id.
|
||||
* On POSIX platforms, the same restrictions mentioned for
|
||||
* g_child_watch_source_new() apply to this function.
|
||||
*
|
||||
* This internally creates a main loop source using
|
||||
* g_child_watch_source_new() and attaches it to the main loop context
|
||||
@ -5451,6 +5463,8 @@ g_child_watch_add_full (gint priority,
|
||||
* g_spawn_close_pid() in the callback function for the source.
|
||||
*
|
||||
* GLib supports only a single callback per process id.
|
||||
* On POSIX platforms, the same restrictions mentioned for
|
||||
* g_child_watch_source_new() apply to this function.
|
||||
*
|
||||
* This internally creates a main loop source using
|
||||
* g_child_watch_source_new() and attaches it to the main loop context
|
||||
|
@ -277,7 +277,8 @@ read_data (GString *str,
|
||||
* the child is stored there; see the documentation of
|
||||
* g_spawn_check_exit_status() for how to use and interpret this.
|
||||
* Note that it is invalid to pass %G_SPAWN_DO_NOT_REAP_CHILD in
|
||||
* @flags.
|
||||
* @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.
|
||||
@ -458,7 +459,7 @@ g_spawn_sync (const gchar *working_directory,
|
||||
{
|
||||
if (exit_status)
|
||||
{
|
||||
g_warning ("In call to g_spawn_sync(), exit status of a child process was requested but ECHILD was received by waitpid(). Most likely the process is ignoring SIGCHLD, or some other thread is invoking waitpid() with a nonpositive first argument; either behavior can break applications that use g_spawn_sync either directly or indirectly.");
|
||||
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.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user