Use pipe2 when available
authorMatthias Clasen <mclasen@redhat.com>
Sat, 20 Jun 2009 03:44:29 +0000 (23:44 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 20 Jun 2009 03:44:29 +0000 (23:44 -0400)
This avoids a small window for races between pipe and fdset.
Reported in bug 579933 by Thiago Macieira.

configure.in
glib/gmain.c

index d253f60bb3a590c4b6a6df743754bd61f1cf76bc..1e070d8a5d3487fa5f0009a39ca6a70e56fab7bc 100644 (file)
@@ -559,15 +559,8 @@ AC_HEADER_STDC
 # Checks for library functions.
 AC_FUNC_VPRINTF
 AC_FUNC_ALLOCA
-AC_CHECK_FUNCS(mmap)
-AC_CHECK_FUNCS(posix_memalign)
-AC_CHECK_FUNCS(memalign)
-AC_CHECK_FUNCS(valloc)
-AC_CHECK_FUNCS(fsync)
-
-AC_CHECK_FUNCS(atexit on_exit)
-
-AC_CHECK_FUNCS(timegm gmtime_r)
+AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2)
+AC_CHECK_FUNCS(atexit on_exit timegm gmtime_r)
 
 AC_CHECK_SIZEOF(char)
 AC_CHECK_SIZEOF(short)
index 331c0a86bc24dbb49a79a9bdc25bd50a239d5b57..6d6b594116b23f5c59d579aaa047960fee75d69a 100644 (file)
@@ -46,6 +46,8 @@
 #define G_MAIN_POLL_DEBUG
 #endif
 
+#define _GNU_SOURCE  /* for pipe2 */
+
 #include "glib.h"
 #include "gthreadprivate.h"
 #include <signal.h>
@@ -402,12 +404,20 @@ g_main_context_init_pipe (GMainContext *context)
 # ifndef G_OS_WIN32
   if (context->wake_up_pipe[0] != -1)
     return;
-  if (pipe (context->wake_up_pipe) < 0)
-    g_error ("Cannot create pipe main loop wake-up: %s\n",
-            g_strerror (errno));
+
+#ifdef HAVE_PIPE2
+  /* if this fails, we fall through and try pipe */
+  pipe2 (context->wake_up_pipe, O_CLOEXEC);
+#endif
+  if (context->wake_up_pipe[0] == -1)
+    {
+      if (pipe (context->wake_up_pipe) < 0)
+        g_error ("Cannot create pipe main loop wake-up: %s\n",
+                g_strerror (errno));
  
-  fcntl (context->wake_up_pipe[0], F_SETFD, FD_CLOEXEC);
-  fcntl (context->wake_up_pipe[1], F_SETFD, FD_CLOEXEC);
+      fcntl (context->wake_up_pipe[0], F_SETFD, FD_CLOEXEC);
+      fcntl (context->wake_up_pipe[1], F_SETFD, FD_CLOEXEC);
+    }
 
   context->wake_up_rec.fd = context->wake_up_pipe[0];
   context->wake_up_rec.events = G_IO_IN;