summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-08-10 23:41:40 +0000
committerUlrich Drepper <drepper@redhat.com>2007-08-10 23:41:40 +0000
commitaa132749c85c62b1e28ae885b84c9fa8aed45dfb (patch)
tree16defacc2d854a94586cdc407a368a614efcb5dd
parent916ee8bcba20a92ce4c4633667b5b37a12f8cba3 (diff)
downloadglibc-aa132749c85c62b1e28ae885b84c9fa8aed45dfb.tar.gz
glibc-aa132749c85c62b1e28ae885b84c9fa8aed45dfb.tar.xz
glibc-aa132749c85c62b1e28ae885b84c9fa8aed45dfb.zip
* nss/nss_files/files-XXX.c (internal_setent): Use O_CLOEXEC if
	possible.
	* nss/nss_files/files-alias.c (internal_setent): Likewise.
	* nss/Makefile (libnss_files-routines): Add files-have_o_cloexec.
	* nss/nss_files/files-have_o_cloexec.c: New file.
-rw-r--r--ChangeLog6
-rw-r--r--nss/Makefile5
-rw-r--r--nss/nss_files/files-XXX.c51
-rw-r--r--nss/nss_files/files-alias.c51
-rw-r--r--nss/nss_files/files-have_o_cloexec.c24
5 files changed, 101 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 6595905c1a..cc2035ff87 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,12 @@
 
 2007-08-10  Ulrich Drepper  <drepper@redhat.com>
 
+	* nss/nss_files/files-XXX.c (internal_setent): Use O_CLOEXEC if
+	possible.
+	* nss/nss_files/files-alias.c (internal_setent): Likewise.
+	* nss/Makefile (libnss_files-routines): Add files-have_o_cloexec.
+	* nss/nss_files/files-have_o_cloexec.c: New file.
+
 	* sysdeps/unix/sysv/linux/shm_open.c (shm_open): Use O_CLOEXEC if
 	available.
 
diff --git a/nss/Makefile b/nss/Makefile
index 320fbbd9f1..f2ecadb2a7 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996,1997,1998,2000,2001,2002 Free Software Foundation, Inc.
+# Copyright (C) 1996-1998,2000,2001,2002,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
@@ -62,7 +62,8 @@ subdir-dirs = $(services:%=nss_%)
 vpath %.c $(subdir-dirs)
 
 
-libnss_files-routines	:= $(addprefix files-,$(databases))
+libnss_files-routines	:= $(addprefix files-,$(databases)) \
+			   files-have_o_cloexec
 distribute		+= files-XXX.c files-parse.c
 
 
diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
index fb13fbe2b6..2149d1c401 100644
--- a/nss/nss_files/files-XXX.c
+++ b/nss/nss_files/files-XXX.c
@@ -1,5 +1,5 @@
 /* Common code for file-based databases in nss_files module.
-   Copyright (C) 1996-1999,2001,2002,2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-1999,2001,2002,2004,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
@@ -24,6 +24,8 @@
 #include <bits/libc-lock.h>
 #include "nsswitch.h"
 
+#include <kernel-features.h>
+
 /* These symbols are defined by the including source file:
 
    ENTNAME -- database name of the structure and functions (hostent, pwent).
@@ -74,29 +76,44 @@ internal_setent (int stayopen)
 
   if (stream == NULL)
     {
-      stream = fopen (DATAFILE, "r");
+      stream = fopen (DATAFILE, "re");
 
       if (stream == NULL)
 	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
       else
 	{
-	  /* We have to make sure the file is  `closed on exec'.  */
-	  int result, flags;
-
-	  result = flags = fcntl (fileno (stream), F_GETFD, 0);
-	  if (result >= 0)
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+	  if (__have_o_cloexec <= 0)
+# endif
 	    {
-	      flags |= FD_CLOEXEC;
-	      result = fcntl (fileno (stream), F_SETFD, flags);
-	    }
-	  if (result < 0)
-	    {
-	      /* Something went wrong.  Close the stream and return a
-		 failure.  */
-	      fclose (stream);
-	      stream = NULL;
-	      status = NSS_STATUS_UNAVAIL;
+	      /* We have to make sure the file is  `closed on exec'.  */
+	      int result;
+	      int flags;
+
+	      result = flags = fcntl (fileno (stream), F_GETFD, 0);
+	      if (result >= 0)
+		{
+# ifdef 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;
+		      result = fcntl (fileno (stream), F_SETFD, flags);
+		    }
+		}
+	      if (result < 0)
+		{
+		  /* Something went wrong.  Close the stream and return a
+		     failure.  */
+		  fclose (stream);
+		  stream = NULL;
+		  status = NSS_STATUS_UNAVAIL;
+		}
 	    }
+#endif
 	}
     }
   else
diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
index c4717e1242..57cc982f77 100644
--- a/nss/nss_files/files-alias.c
+++ b/nss/nss_files/files-alias.c
@@ -1,5 +1,5 @@
 /* Mail alias file parser in nss_files module.
-   Copyright (C) 1996,97,98,99,2002,2006 Free Software Foundation, Inc.
+   Copyright (C) 1996,97,98,99,2002,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -27,6 +27,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <kernel-features.h>
+
 #include "nsswitch.h"
 
 /* Locks the static variables in this file.  */
@@ -46,29 +48,44 @@ internal_setent (void)
 
   if (stream == NULL)
     {
-      stream = fopen ("/etc/aliases", "r");
+      stream = fopen ("/etc/aliases", "re");
 
       if (stream == NULL)
 	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
       else
 	{
-	  /* We have to make sure the file is  `closed on exec'.  */
-	  int result, flags;
-
-	  result = flags = fcntl (fileno (stream), F_GETFD, 0);
-	  if (result >= 0)
-	    {
-	      flags |= FD_CLOEXEC;
-	      result = fcntl (fileno (stream), F_SETFD, flags);
-	    }
-	  if (result < 0)
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+	  if (__have_o_cloexec <= 0)
+# endif
 	    {
-	      /* Something went wrong.  Close the stream and return a
-		 failure.  */
-	      fclose (stream);
-	      stream = NULL;
-	      status = NSS_STATUS_UNAVAIL;
+	      /* We have to make sure the file is  `closed on exec'.  */
+	      int result;
+	      int flags;
+
+	      result = flags = fcntl (fileno (stream), F_GETFD, 0);
+	      if (result >= 0)
+		{
+# ifdef 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;
+		      result = fcntl (fileno (stream), F_SETFD, flags);
+		    }
+		}
+	      if (result < 0)
+		{
+		  /* Something went wrong.  Close the stream and return a
+		     failure.  */
+		  fclose (stream);
+		  stream = NULL;
+		  status = NSS_STATUS_UNAVAIL;
+		}
 	    }
+#endif
 	}
     }
   else
diff --git a/nss/nss_files/files-have_o_cloexec.c b/nss/nss_files/files-have_o_cloexec.c
new file mode 100644
index 0000000000..a83e8a4487
--- /dev/null
+++ b/nss/nss_files/files-have_o_cloexec.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fcntl.h>
+#include <kernel-features.h>
+
+#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC
+int __have_o_cloexec;
+#endif