about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-08-10 20:10:11 +0000
committerUlrich Drepper <drepper@redhat.com>2007-08-10 20:10:11 +0000
commitbfcd38238b75faea59b3e461277510ff9031473f (patch)
tree961a81c843c5d2b8e0de719d6e50ddfd9cc7db31
parent1e286653495caf9b5eb392b82365b5197a9b353f (diff)
downloadglibc-bfcd38238b75faea59b3e461277510ff9031473f.tar.gz
glibc-bfcd38238b75faea59b3e461277510ff9031473f.tar.xz
glibc-bfcd38238b75faea59b3e461277510ff9031473f.zip
(shm_open): Use O_CLOEXEC is available.
-rw-r--r--sysdeps/unix/sysv/linux/shm_open.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/sysdeps/unix/sysv/linux/shm_open.c b/sysdeps/unix/sysv/linux/shm_open.c
index 0d40632e5f..0628427680 100644
--- a/sysdeps/unix/sysv/linux/shm_open.c
+++ b/sysdeps/unix/sysv/linux/shm_open.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000,2001,2002,2003,2004,2006 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2004,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -46,6 +46,11 @@ static const char defaultdir[] = "/dev/shm/";
 __libc_once_define (static, once);
 
 
+#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC
+static bool have_o_cloexec;
+#endif
+
+
 /* Determine where the shmfs is mounted (if at all).  */
 static void
 where_is_shmfs (void)
@@ -160,6 +165,10 @@ shm_open (const char *name, int oflag, mode_t mode)
   __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
 	     name, namelen + 1);
 
+#ifdef O_CLOEXEC
+  oflag |= O_CLOEXEC;
+#endif
+
   /* And get the file descriptor.
      XXX Maybe we should test each descriptor whether it really is for a
      file on the shmfs.  If this is what should be done the whole function
@@ -168,23 +177,37 @@ shm_open (const char *name, int oflag, mode_t mode)
   fd = open (fname, oflag | O_NOFOLLOW, mode);
   if (fd != -1)
     {
-      /* We got a descriptor.  Now set the FD_CLOEXEC bit.  */
-      int flags = fcntl (fd, F_GETFD, 0);
-
-      if (__builtin_expect (flags, 0) >= 0)
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+      if (have_o_cloexec <= 0)
+# endif
 	{
-	  flags |= FD_CLOEXEC;
-	  flags = fcntl (fd, F_SETFD, flags);
-	}
-
-      if (flags == -1)
-	{
-	  /* Something went wrong.  We cannot return the descriptor.  */
-	  int save_errno = errno;
-	  close (fd);
-	  fd = -1;
-	  __set_errno (save_errno);
+	  /* We got a descriptor.  Now set the FD_CLOEXEC bit.  */
+	  int flags = fcntl (fd, F_GETFD, 0);
+
+	  if (__builtin_expect (flags, 0) >= 0)
+	    {
+# ifndef O_CLOEXEC
+	      if (have_o_cloexec == 0)
+		have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+	      if (have_o_cloexec < 0)
+# endif
+		{
+		  flags |= FD_CLOEXEC;
+		  flags = fcntl (fd, F_SETFD, flags);
+		}
+	    }
+
+	  if (flags == -1)
+	    {
+	      /* Something went wrong.  We cannot return the descriptor.  */
+	      int save_errno = errno;
+	      close (fd);
+	      fd = -1;
+	      __set_errno (save_errno);
+	    }
 	}
+#endif
     }
   else if (__builtin_expect (errno == EISDIR, 0))
     /* It might be better to fold this error with EINVAL since