[glib] g_unix_set_fd_nonblocking: New API to control file descriptor blocking state
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] g_unix_set_fd_nonblocking: New API to control file descriptor blocking state
- Date: Tue, 3 May 2011 14:15:01 +0000 (UTC)
commit ed37970a0405b5681bcd6449d4dc1b4f9080c4fa
Author: Colin Walters <walters verbum org>
Date: Tue May 3 09:52:10 2011 -0400
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
gio/gcancellable.c | 27 +++++----------------------
gio/gsocket.c | 17 ++++++++---------
glib/glib-unix.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
glib/glib-unix.h | 4 ++++
glib/glib.symbols | 1 +
glib/gmain.c | 2 +-
6 files changed, 69 insertions(+), 32 deletions(-)
---
diff --git a/gio/gcancellable.c b/gio/gcancellable.c
index c37baff..32f5081 100644
--- a/gio/gcancellable.c
+++ b/gio/gcancellable.c
@@ -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]);
diff --git a/gio/gsocket.c b/gio/gsocket.c
index d0219c1..4b5f18a 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -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;
diff --git a/glib/glib-unix.c b/glib/glib-unix.c
index cf4748b..5a0f7f7 100644
--- a/glib/glib-unix.c
+++ b/glib/glib-unix.c
@@ -136,6 +136,56 @@ g_unix_pipe_flags (int *fds,
}
/**
+ * 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
*
diff --git a/glib/glib-unix.h b/glib/glib-unix.h
index 55aaf25..de38c54 100644
--- a/glib/glib-unix.h
+++ b/glib/glib-unix.h
@@ -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,
diff --git a/glib/glib.symbols b/glib/glib.symbols
index bc1c323..12b7430 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -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
diff --git a/glib/gmain.c b/glib/gmain.c
index f31405a..efcdcc3 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -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)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]