aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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