mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-29 23:42:17 +01:00
Revert "gmain: Add private API to create Unix child watch that uses waitid()"
This reverts commit 47d82f236d.
This commit is contained in:
@@ -992,7 +992,7 @@ AC_MSG_RESULT(unsigned $glib_size_type)
|
|||||||
|
|
||||||
# Check for some functions
|
# Check for some functions
|
||||||
AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk memmem)
|
AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk memmem)
|
||||||
AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid getresuid waitid)
|
AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid getresuid)
|
||||||
AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getfsstat getvfsstat)
|
AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getfsstat getvfsstat)
|
||||||
# Check for high-resolution sleep functions
|
# Check for high-resolution sleep functions
|
||||||
AC_CHECK_FUNCS(splice)
|
AC_CHECK_FUNCS(splice)
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ glib__private__ (void)
|
|||||||
g_get_worker_context,
|
g_get_worker_context,
|
||||||
|
|
||||||
g_check_setuid,
|
g_check_setuid,
|
||||||
g_main_context_new_with_next_id,
|
g_main_context_new_with_next_id
|
||||||
g_child_watch_source_new_with_flags
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return &table;
|
return &table;
|
||||||
|
|||||||
@@ -23,11 +23,6 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "gwakeup.h"
|
#include "gwakeup.h"
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
_G_CHILD_WATCH_FLAGS_NONE = 0,
|
|
||||||
_G_CHILD_WATCH_FLAGS_WNOWAIT = (1 << 0)
|
|
||||||
} _GChildWatchFlags;
|
|
||||||
|
|
||||||
GMainContext * g_get_worker_context (void);
|
GMainContext * g_get_worker_context (void);
|
||||||
gboolean g_check_setuid (void);
|
gboolean g_check_setuid (void);
|
||||||
GMainContext * g_main_context_new_with_next_id (guint next_id);
|
GMainContext * g_main_context_new_with_next_id (guint next_id);
|
||||||
@@ -38,9 +33,6 @@ GLIB_AVAILABLE_IN_ALL
|
|||||||
gchar *_glib_get_locale_dir (void);
|
gchar *_glib_get_locale_dir (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GSource * g_child_watch_source_new_with_flags (GPid pid,
|
|
||||||
gint flags);
|
|
||||||
|
|
||||||
#define GLIB_PRIVATE_CALL(symbol) (glib__private__()->symbol)
|
#define GLIB_PRIVATE_CALL(symbol) (glib__private__()->symbol)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -57,8 +49,6 @@ typedef struct {
|
|||||||
|
|
||||||
gboolean (* g_check_setuid) (void);
|
gboolean (* g_check_setuid) (void);
|
||||||
GMainContext * (* g_main_context_new_with_next_id) (guint next_id);
|
GMainContext * (* g_main_context_new_with_next_id) (guint next_id);
|
||||||
GSource * (* g_child_watch_source_new_with_flags) (GPid pid,
|
|
||||||
gint flags);
|
|
||||||
/* Add other private functions here, initialize them in glib-private.c */
|
/* Add other private functions here, initialize them in glib-private.c */
|
||||||
} GLibPrivateVTable;
|
} GLibPrivateVTable;
|
||||||
|
|
||||||
|
|||||||
163
glib/gmain.c
163
glib/gmain.c
@@ -293,9 +293,7 @@ struct _GChildWatchSource
|
|||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
GPollFD poll;
|
GPollFD poll;
|
||||||
#else /* G_OS_WIN32 */
|
#else /* G_OS_WIN32 */
|
||||||
guint child_exited : 1;
|
gboolean child_exited;
|
||||||
guint wnowait : 1;
|
|
||||||
guint reserved : 30;
|
|
||||||
#endif /* G_OS_WIN32 */
|
#endif /* G_OS_WIN32 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4775,82 +4773,6 @@ wake_source (GSource *source)
|
|||||||
G_UNLOCK(main_context_list);
|
G_UNLOCK(main_context_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a hack; we want to use the newer waitid() call, but the use
|
|
||||||
* of the waitpid() status code API is baked into the GChildWatchSource
|
|
||||||
* callback signature, so we need to synthesize it from the siginfo_t
|
|
||||||
* we get from waitid().
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_WAITID
|
|
||||||
#define __G_MAKE_EXITSTATUS(ecode, signum) ((ecode) << 8 | (signum))
|
|
||||||
static gint
|
|
||||||
waitpid_status_from_siginfo (siginfo_t *siginfo)
|
|
||||||
{
|
|
||||||
G_STATIC_ASSERT(((WIFEXITED (__G_MAKE_EXITSTATUS (1, 0))) && \
|
|
||||||
!(WIFSIGNALED (__G_MAKE_EXITSTATUS (1, 0))) && \
|
|
||||||
(WEXITSTATUS (__G_MAKE_EXITSTATUS (1, 0)) == 1)));
|
|
||||||
G_STATIC_ASSERT((!WIFEXITED (__G_MAKE_EXITSTATUS (0, 1))) && \
|
|
||||||
(WIFSIGNALED (__G_MAKE_EXITSTATUS (0, 1))) && \
|
|
||||||
(WTERMSIG (__G_MAKE_EXITSTATUS (0, 1)) == 1));
|
|
||||||
if (siginfo->si_code == CLD_EXITED)
|
|
||||||
return __G_MAKE_EXITSTATUS(siginfo->si_status, 0);
|
|
||||||
else if (siginfo->si_code == CLD_KILLED || siginfo->si_code == CLD_DUMPED)
|
|
||||||
return __G_MAKE_EXITSTATUS(0, siginfo->si_status);
|
|
||||||
else
|
|
||||||
return __G_MAKE_EXITSTATUS(0xFF, 0);
|
|
||||||
}
|
|
||||||
#undef __G_MAKE_EXITSTATUS
|
|
||||||
#endif /* HAVE_WAITID */
|
|
||||||
|
|
||||||
/* Returns TRUE if we need to wake the source */
|
|
||||||
static gboolean
|
|
||||||
unix_child_watch_source_waitpid (GChildWatchSource *source)
|
|
||||||
{
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
if (source->child_exited)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
#ifdef HAVE_WAITID
|
|
||||||
if (source->wnowait)
|
|
||||||
{
|
|
||||||
siginfo_t siginfo;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
siginfo.si_pid = 0;
|
|
||||||
do
|
|
||||||
r = waitid (P_PID, (id_t)source->pid, &siginfo, WEXITED | WNOHANG | WNOWAIT);
|
|
||||||
while (r == -1 && errno == EINTR);
|
|
||||||
|
|
||||||
if (r == 0 && siginfo.si_pid == source->pid)
|
|
||||||
{
|
|
||||||
source->child_exited = TRUE;
|
|
||||||
source->child_status = waitpid_status_from_siginfo (&siginfo);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
do
|
|
||||||
pid = waitpid (source->pid, &source->child_status, WNOHANG);
|
|
||||||
while (pid == -1 && errno == EINTR);
|
|
||||||
|
|
||||||
if (pid > 0)
|
|
||||||
{
|
|
||||||
source->child_exited = TRUE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
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.");
|
|
||||||
source->child_exited = TRUE;
|
|
||||||
source->child_status = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dispatch_unix_signals (void)
|
dispatch_unix_signals (void)
|
||||||
{
|
{
|
||||||
@@ -4877,9 +4799,28 @@ dispatch_unix_signals (void)
|
|||||||
for (node = unix_child_watches; node; node = node->next)
|
for (node = unix_child_watches; node; node = node->next)
|
||||||
{
|
{
|
||||||
GChildWatchSource *source = node->data;
|
GChildWatchSource *source = node->data;
|
||||||
|
|
||||||
if (unix_child_watch_source_waitpid (source))
|
if (!source->child_exited)
|
||||||
wake_source ((GSource *) source);
|
{
|
||||||
|
pid_t pid;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pid = waitpid (source->pid, &source->child_status, WNOHANG);
|
||||||
|
if (pid > 0)
|
||||||
|
{
|
||||||
|
source->child_exited = TRUE;
|
||||||
|
wake_source ((GSource *) source);
|
||||||
|
}
|
||||||
|
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.");
|
||||||
|
source->child_exited = TRUE;
|
||||||
|
source->child_status = 0;
|
||||||
|
wake_source ((GSource *) source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (pid == -1 && errno == EINTR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5071,43 +5012,6 @@ g_unix_signal_handler (int signum)
|
|||||||
|
|
||||||
#endif /* !G_OS_WIN32 */
|
#endif /* !G_OS_WIN32 */
|
||||||
|
|
||||||
GSource *
|
|
||||||
g_child_watch_source_new_with_flags (GPid pid,
|
|
||||||
gint flags)
|
|
||||||
{
|
|
||||||
GSource *source;
|
|
||||||
GChildWatchSource *child_watch_source;
|
|
||||||
|
|
||||||
#if defined(G_OS_UNIX) && !defined(HAVE_WAITID)
|
|
||||||
if (flags & _G_CHILD_WATCH_FLAGS_WNOWAIT)
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
|
|
||||||
child_watch_source = (GChildWatchSource *)source;
|
|
||||||
|
|
||||||
child_watch_source->pid = pid;
|
|
||||||
#if defined(G_OS_UNIX) && defined(HAVE_WAITID)
|
|
||||||
if (flags & _G_CHILD_WATCH_FLAGS_WNOWAIT)
|
|
||||||
child_watch_source->wnowait = TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
|
||||||
child_watch_source->poll.fd = (gintptr) pid;
|
|
||||||
child_watch_source->poll.events = G_IO_IN;
|
|
||||||
|
|
||||||
g_source_add_poll (source, &child_watch_source->poll);
|
|
||||||
#else /* G_OS_WIN32 */
|
|
||||||
G_LOCK (unix_signal_lock);
|
|
||||||
ensure_unix_signal_handler_installed_unlocked (SIGCHLD);
|
|
||||||
unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source);
|
|
||||||
unix_child_watch_source_waitpid (child_watch_source);
|
|
||||||
G_UNLOCK (unix_signal_lock);
|
|
||||||
#endif /* G_OS_WIN32 */
|
|
||||||
|
|
||||||
return source;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 pid of a child process. On
|
||||||
@@ -5140,7 +5044,26 @@ g_child_watch_source_new_with_flags (GPid pid,
|
|||||||
GSource *
|
GSource *
|
||||||
g_child_watch_source_new (GPid pid)
|
g_child_watch_source_new (GPid pid)
|
||||||
{
|
{
|
||||||
return g_child_watch_source_new_with_flags (pid, 0);
|
GSource *source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
|
||||||
|
GChildWatchSource *child_watch_source = (GChildWatchSource *)source;
|
||||||
|
|
||||||
|
child_watch_source->pid = pid;
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
child_watch_source->poll.fd = (gintptr) pid;
|
||||||
|
child_watch_source->poll.events = G_IO_IN;
|
||||||
|
|
||||||
|
g_source_add_poll (source, &child_watch_source->poll);
|
||||||
|
#else /* G_OS_WIN32 */
|
||||||
|
G_LOCK (unix_signal_lock);
|
||||||
|
ensure_unix_signal_handler_installed_unlocked (SIGCHLD);
|
||||||
|
unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source);
|
||||||
|
if (waitpid (pid, &child_watch_source->child_status, WNOHANG) > 0)
|
||||||
|
child_watch_source->child_exited = TRUE;
|
||||||
|
G_UNLOCK (unix_signal_lock);
|
||||||
|
#endif /* G_OS_WIN32 */
|
||||||
|
|
||||||
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user