diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-08-03 04:09:03 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-08-03 04:09:03 +0000 |
commit | cbf0489bcf3eebeeba595a514461057a4e2f1e8b (patch) | |
tree | 5494b98023b95a29643094578424382515a41724 /sysdeps/unix/opendir.c | |
parent | fa39685d5c7df2502213418bead44e9543a9b9ec (diff) | |
download | glibc-cbf0489bcf3eebeeba595a514461057a4e2f1e8b.tar.gz glibc-cbf0489bcf3eebeeba595a514461057a4e2f1e8b.tar.xz glibc-cbf0489bcf3eebeeba595a514461057a4e2f1e8b.zip |
* 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.
Diffstat (limited to 'sysdeps/unix/opendir.c')
-rw-r--r-- | sysdeps/unix/opendir.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/sysdeps/unix/opendir.c b/sysdeps/unix/opendir.c index 36fb6f458d..34f5b719d3 100644 --- a/sysdeps/unix/opendir.c +++ b/sysdeps/unix/opendir.c @@ -31,6 +31,7 @@ #include <dirstream.h> #include <not-cancel.h> +#include <kernel-features.h> /* 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 |