g_child_watch_source_new: POSIX pid must be positive

If we used a non-positive pid, we'd call waitpid(that_pid, ...)
which is exactly the situation this function can't deal with.

On Windows, GPid is a HANDLE (pointer), so I don't think the same thing
applies.

Bug: https://bugzilla.gnome.org/show_bug.cgi?id=723743
Reviewed-by: Ryan Lortie
This commit is contained in:
Simon McVittie 2014-02-06 17:48:44 +00:00
parent a3cb5ce33b
commit 125913e9fe

View File

@ -4868,6 +4868,8 @@ dispatch_unix_signals_unlocked (void)
pid_t pid; pid_t pid;
do do
{ {
g_assert (source->pid > 0);
pid = waitpid (source->pid, &source->child_status, WNOHANG); pid = waitpid (source->pid, &source->child_status, WNOHANG);
if (pid > 0) if (pid > 0)
{ {
@ -5096,7 +5098,7 @@ g_unix_signal_handler (int signum)
/** /**
* g_child_watch_source_new: * g_child_watch_source_new:
* @pid: process to watch. On POSIX the pid of a child process. On * @pid: process to watch. On POSIX the positive pid of a child process. On
* Windows a handle for a process (which doesn't have to be a child). * Windows a handle for a process (which doesn't have to be a child).
* *
* Creates a new child_watch source. * Creates a new child_watch source.
@ -5118,6 +5120,10 @@ g_unix_signal_handler (int signum)
* argument in the application. Calling waitpid() for individual * argument in the application. Calling waitpid() for individual
* pids will still work fine. * pids will still work fine.
* *
* 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).
*
* Return value: the newly-created child watch source * Return value: the newly-created child watch source
* *
* Since: 2.4 * Since: 2.4
@ -5125,8 +5131,15 @@ g_unix_signal_handler (int signum)
GSource * GSource *
g_child_watch_source_new (GPid pid) g_child_watch_source_new (GPid pid)
{ {
GSource *source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource)); GSource *source;
GChildWatchSource *child_watch_source = (GChildWatchSource *)source; GChildWatchSource *child_watch_source;
#ifndef G_OS_WIN32
g_return_val_if_fail (pid > 0, NULL);
#endif
source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
child_watch_source = (GChildWatchSource *)source;
child_watch_source->pid = pid; child_watch_source->pid = pid;
@ -5151,7 +5164,7 @@ g_child_watch_source_new (GPid pid)
* g_child_watch_add_full: * g_child_watch_add_full:
* @priority: the priority of the idle source. Typically this will be in the * @priority: the priority of the idle source. Typically this will be in the
* range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE. * range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
* @pid: process to watch. On POSIX the pid of a child process. On * @pid: process to watch. On POSIX the positive pid of a child process. On
* Windows a handle for a process (which doesn't have to be a child). * Windows a handle for a process (which doesn't have to be a child).
* @function: function to call * @function: function to call
* @data: data to pass to @function * @data: data to pass to @function
@ -5196,6 +5209,9 @@ g_child_watch_add_full (gint priority,
guint id; guint id;
g_return_val_if_fail (function != NULL, 0); g_return_val_if_fail (function != NULL, 0);
#ifndef G_OS_WIN32
g_return_val_if_fail (pid > 0, 0);
#endif
source = g_child_watch_source_new (pid); source = g_child_watch_source_new (pid);
@ -5211,8 +5227,9 @@ g_child_watch_add_full (gint priority,
/** /**
* g_child_watch_add: * g_child_watch_add:
* @pid: process id to watch. On POSIX the pid of a child process. On * @pid: process id to watch. On POSIX the positive pid of a child
* Windows a handle for a process (which doesn't have to be a child). * process. On Windows a handle for a process (which doesn't have to be
* a child).
* @function: function to call * @function: function to call
* @data: data to pass to @function * @data: data to pass to @function
* *