Skip to content

Commit

Permalink
(shm_open): Use O_CLOEXEC is available.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ulrich Drepper committed Aug 10, 2007
1 parent 1e28665 commit bfcd382
Showing 1 changed file with 39 additions and 16 deletions.
55 changes: 39 additions & 16 deletions sysdeps/unix/sysv/linux/shm_open.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit bfcd382

Please sign in to comment.