* login/utmp_file.c (setutent_file): Use O_CLOEXEC if possible.
authorUlrich Drepper <drepper@redhat.com>
Sun, 22 Jul 2007 19:02:23 +0000 (19:02 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 22 Jul 2007 19:02:23 +0000 (19:02 +0000)
ChangeLog
login/utmp_file.c

index b7ee456..1dbfa13 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2007-07-22  Ulrich Drepper  <drepper@redhat.com>
 
+       * 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.
index 871c856..4a9e409 100644 (file)
@@ -27,6 +27,7 @@
 #include <unistd.h>
 #include <utmp.h>
 #include <not-cancel.h>
+#include <kernel-features.h>
 
 #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);