mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 14:06:15 +01:00
g_unix_set_fd_nonblocking: New API to control file descriptor blocking state
And use it in relevant places in GLib. https://bugzilla.gnome.org/show_bug.cgi?id=649225
This commit is contained in:
parent
e08e70e08d
commit
ed37970a04
@ -21,11 +21,10 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#include "glib.h"
|
||||
#ifdef G_OS_UNIX
|
||||
#include "glib-unix.h"
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <gioerror.h>
|
||||
#ifdef G_OS_WIN32
|
||||
#include <windows.h>
|
||||
@ -193,22 +192,6 @@ g_cancellable_class_init (GCancellableClass *klass)
|
||||
}
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
static void
|
||||
set_fd_nonblocking (int fd)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
glong fcntl_flags;
|
||||
fcntl_flags = fcntl (fd, F_GETFL);
|
||||
|
||||
#ifdef O_NONBLOCK
|
||||
fcntl_flags |= O_NONBLOCK;
|
||||
#else
|
||||
fcntl_flags |= O_NDELAY;
|
||||
#endif
|
||||
|
||||
fcntl (fd, F_SETFL, fcntl_flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
set_fd_close_exec (int fd)
|
||||
@ -235,8 +218,8 @@ g_cancellable_open_pipe (GCancellable *cancellable)
|
||||
/* Make them nonblocking, just to be sure we don't block
|
||||
* on errors and stuff
|
||||
*/
|
||||
set_fd_nonblocking (priv->cancel_pipe[0]);
|
||||
set_fd_nonblocking (priv->cancel_pipe[1]);
|
||||
g_unix_set_fd_nonblocking (priv->cancel_pipe[0], TRUE, NULL);
|
||||
g_unix_set_fd_nonblocking (priv->cancel_pipe[1], TRUE, NULL);
|
||||
set_fd_close_exec (priv->cancel_pipe[0]);
|
||||
set_fd_close_exec (priv->cancel_pipe[1]);
|
||||
|
||||
|
@ -29,6 +29,10 @@
|
||||
|
||||
#include "gsocket.h"
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
#include "glib-unix.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
@ -240,22 +244,17 @@ static void
|
||||
set_fd_nonblocking (int fd)
|
||||
{
|
||||
#ifndef G_OS_WIN32
|
||||
glong arg;
|
||||
GError *error = NULL;
|
||||
#else
|
||||
gulong arg;
|
||||
#endif
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
if ((arg = fcntl (fd, F_GETFL, NULL)) < 0)
|
||||
if (!g_unix_set_fd_nonblocking (fd, TRUE, &error))
|
||||
{
|
||||
g_warning ("Error getting socket status flags: %s", socket_strerror (errno));
|
||||
arg = 0;
|
||||
g_warning ("Error setting socket nonblocking: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
arg = arg | O_NONBLOCK;
|
||||
|
||||
if (fcntl (fd, F_SETFL, arg) < 0)
|
||||
g_warning ("Error setting socket status flags: %s", socket_strerror (errno));
|
||||
#else
|
||||
arg = TRUE;
|
||||
|
||||
|
@ -135,6 +135,56 @@ g_unix_pipe_flags (int *fds,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_unix_set_fd_nonblocking:
|
||||
* @fd: A file descriptor
|
||||
* @nonblock: If %TRUE, set the descriptor to be non-blocking
|
||||
* @error: a #GError
|
||||
*
|
||||
* Control the non-blocking state of the given file descriptor,
|
||||
* according to @nonblock. On most systems this uses %O_NONBLOCK, but
|
||||
* on some older ones may use %O_NDELAY.
|
||||
*
|
||||
* Returns: %TRUE if successful
|
||||
*/
|
||||
gboolean
|
||||
g_unix_set_fd_nonblocking (gint fd,
|
||||
gboolean nonblock,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
glong fcntl_flags;
|
||||
fcntl_flags = fcntl (fd, F_GETFL);
|
||||
|
||||
if (fcntl_flags == -1)
|
||||
return g_unix_set_error_from_errno (error);
|
||||
|
||||
if (nonblock)
|
||||
{
|
||||
#ifdef O_NONBLOCK
|
||||
fcntl_flags |= O_NONBLOCK;
|
||||
#else
|
||||
fcntl_flags |= O_NDELAY;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef O_NONBLOCK
|
||||
fcntl_flags &= ~O_NONBLOCK;
|
||||
#else
|
||||
fcntl_flags &= ~O_NDELAY;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (fcntl (fd, F_SETFL, fcntl_flags) == -1)
|
||||
return g_unix_set_error_from_errno (error);
|
||||
return TRUE;
|
||||
#else
|
||||
return g_unix_set_error_from_errno_saved (error, EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* g_unix_signal_source_new:
|
||||
* @signum: A signal number
|
||||
|
@ -61,6 +61,10 @@ gboolean g_unix_pipe_flags (int *fds,
|
||||
int flags,
|
||||
GError **error);
|
||||
|
||||
gboolean g_unix_set_fd_nonblocking (gint fd,
|
||||
gboolean nonblock,
|
||||
GError **error);
|
||||
|
||||
GSource *g_unix_signal_source_new (int signum);
|
||||
|
||||
guint g_unix_signal_add_watch_full (int signum,
|
||||
|
@ -1983,6 +1983,7 @@ g_hostname_to_unicode
|
||||
#ifdef G_OS_UNIX
|
||||
g_unix_pipe_flags
|
||||
g_unix_error_quark
|
||||
g_unix_set_fd_nonblocking
|
||||
g_unix_signal_source_new
|
||||
g_unix_signal_add_watch_full
|
||||
#endif
|
||||
|
@ -4638,7 +4638,7 @@ init_unix_signal_wakeup_state_unlocked (void)
|
||||
|
||||
if (!g_unix_pipe_flags (unix_signal_wake_up_pipe, FD_CLOEXEC, &error))
|
||||
g_error ("Cannot create UNIX signal wake up pipe: %s\n", error->message);
|
||||
fcntl (unix_signal_wake_up_pipe[1], F_SETFL, O_NONBLOCK | fcntl (unix_signal_wake_up_pipe[1], F_GETFL));
|
||||
g_unix_set_fd_nonblocking (unix_signal_wake_up_pipe[1], TRUE, NULL);
|
||||
|
||||
/* We create a helper thread that polls on the wakeup pipe indefinitely */
|
||||
if (g_thread_create (unix_signal_helper_thread, NULL, FALSE, &error) == NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user