diff --git a/ChangeLog b/ChangeLog index b7ee456696..1dbfa13ef1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2007-07-22 Ulrich Drepper + * login/utmp_file.c (setutent_file): Use O_CLOEXEC if possible. + * libio/fileops.c (_IO_new_file_fopen): Recognize 'e' flag and set O_CLOEXEC is needed. * nis/nss_compat/compat-grp.c: Use 'e' flag when opening file. diff --git a/login/utmp_file.c b/login/utmp_file.c index 871c856071..4a9e409454 100644 --- a/login/utmp_file.c +++ b/login/utmp_file.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "utmp-private.h" #include "utmp-equal.h" @@ -140,24 +141,47 @@ setutent_file (void) file_name = TRANSFORM_UTMP_FILE_NAME (__libc_utmp_file_name); - file_fd = open_not_cancel_2 (file_name, O_RDWR | O_LARGEFILE); +#ifdef O_CLOEXEC +# define O_flags O_LARGEFILE | O_CLOEXEC +#else +# define O_flags O_LARGEFILE +#endif + file_fd = open_not_cancel_2 (file_name, O_RDWR | O_flags); if (file_fd == -1) { /* Hhm, read-write access did not work. Try read-only. */ - file_fd = open_not_cancel_2 (file_name, O_RDONLY | O_LARGEFILE); + file_fd = open_not_cancel_2 (file_name, O_RDONLY | O_flags); if (file_fd == -1) return 0; } - /* We have to make sure the file is `closed on exec'. */ - result = fcntl_not_cancel (file_fd, F_GETFD, 0); - if (result >= 0) - result = fcntl_not_cancel (file_fd, F_SETFD, result | FD_CLOEXEC); - if (result == -1) +#ifndef __ASSUME_O_CLOEXEC +# ifdef O_CLOEXEC + static int have_o_cloexec; + + if (have_o_cloexec <= 0) +# endif { - close_not_cancel_no_status (file_fd); - return 0; + /* We have to make sure the file is `closed on exec'. */ + result = fcntl_not_cancel (file_fd, F_GETFD, 0); + if (result >= 0) + { +# ifdef O_CLOEXEC + if (have_o_cloexec == 0) + have_o_cloexec = (result & FD_CLOEXEC) ? 1 : -1; +# endif + + result = fcntl_not_cancel (file_fd, F_SETFD, + result | FD_CLOEXEC); + } + + if (result == -1) + { + close_not_cancel_no_status (file_fd); + return 0; + } } +#endif } __lseek64 (file_fd, 0, SEEK_SET);