From cbf0489bcf3eebeeba595a514461057a4e2f1e8b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 3 Aug 2007 04:09:03 +0000 Subject: * io/Makefile (aux): Add have_o_cloexec. * include/fcntl.h: Declare __have_o_cloexec. * io/have_o_cloexec.c: New file. * sysdeps/unix/opendir.c (__opendir): Use O_CLOEXEC is available. (__alloc_dir): If O_CLOEXEC has been used, don't duplicate the fcntl call if not necessary. * login/utmp_file.c (setutent_file): Use __have_o_cloexec instead of local variable. --- sysdeps/unix/opendir.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'sysdeps/unix') diff --git a/sysdeps/unix/opendir.c b/sysdeps/unix/opendir.c index 36fb6f4..34f5b71 100644 --- a/sysdeps/unix/opendir.c +++ b/sysdeps/unix/opendir.c @@ -31,6 +31,7 @@ #include #include +#include /* opendir() must not accidentally open something other than a directory. @@ -110,7 +111,11 @@ __opendir (const char *name) } } - int fd = open_not_cancel_2 (name, O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE); + int flags = O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE; +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + int fd = open_not_cancel_2 (name, flags); if (__builtin_expect (fd, 0) < 0) return NULL; @@ -138,12 +143,33 @@ __opendir (const char *name) weak_alias (__opendir, opendir) +#ifdef __ASSUME_O_CLOEXEC +# define check_have_o_cloexec(fd) 1 +#else +static int +check_have_o_cloexec (int fd) +{ + if (__have_o_cloexec == 0) + __have_o_cloexec = (__fcntl (fd, F_GETFD, 0) & FD_CLOEXEC) == 0 ? -1 : 1; + return __have_o_cloexec > 0; +} +#endif + + DIR * internal_function __alloc_dir (int fd, bool close_fd, const struct stat64 *statp) { - if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0) - goto lose; + /* We always have to set the close-on-exit flag if the user provided + the file descriptor. Otherwise only if we have no working + O_CLOEXEC support. */ +#ifdef O_CLOEXEC + if (! close_fd || ! check_have_o_cloexec (fd)) +#endif + { + if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0) + goto lose; + } size_t allocation; #ifdef _STATBUF_ST_BLKSIZE -- cgit v1.1