about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-10-15 04:59:16 +0000
committerUlrich Drepper <drepper@redhat.com>2007-10-15 04:59:16 +0000
commit8d97ac135571fb7415d4331d925744eaae6df2e0 (patch)
treeaed196608a7ce26f9866ff459613850b8ef43f73
parent1b6aa63f4e5e8f271f4bb8269edb18842d5941e6 (diff)
downloadglibc-cvs/fedora-glibc-20071015T0728.tar.gz
glibc-cvs/fedora-glibc-20071015T0728.tar.xz
glibc-cvs/fedora-glibc-20071015T0728.zip
* posix/glob.c: Reimplement link_exists_p to use fstatat64. cvs/fedora-glibc-20071015T0728
-rw-r--r--ChangeLog2
-rw-r--r--posix/glob.c31
2 files changed, 30 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 17b8bc05d8..89156b9497 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2007-10-14  Ulrich Drepper  <drepper@redhat.com>
 
+	* posix/glob.c: Reimplement link_exists_p to use fstatat64.
+
 	* posix/glob.c: Add some branch prediction throughout.
 
 	* nscd/nscd_getgr_r.c (nscd_getgr_r): Store result of successful
diff --git a/posix/glob.c b/posix/glob.c
index 38110fd135..b7d9617267 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -1222,21 +1222,42 @@ weak_alias (__glob_pattern_p, glob_pattern_p)
    allocated with alloca to be recycled.  */
 #if !defined _LIBC || !defined GLOB_ONLY_P
 static int
-link_exists_p (const char *dir, size_t dirlen, const char *fname,
-	       glob_t *pglob, int flags)
+__attribute_noinline__
+link_exists2_p (const char *dir, size_t dirlen, const char *fname,
+	       glob_t *pglob
+# ifndef _LIBC
+		, int flags
+# endif
+		)
 {
   size_t fnamelen = strlen (fname);
   char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1);
   struct stat st;
+# ifndef _LIBC
   struct_stat64 st64;
+# endif
 
   mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1),
 	   fname, fnamelen + 1);
 
+# ifdef _LIBC
+  return (*pglob->gl_stat) (fullname, &st) == 0;
+# else
   return ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
 	   ? (*pglob->gl_stat) (fullname, &st)
 	   : __stat64 (fullname, &st64)) == 0);
+# endif
 }
+# ifdef _LIBC
+#  define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \
+  (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)			      \
+   ? link_exists2_p (dirname, dirnamelen, fname, pglob)			      \
+   : ({ struct stat64 st64;						      \
+       __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0) == 0; }))
+# else
+#  define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \
+  link_exists2_p (dirname, dirnamelen, fname, pglob, flags)
+# endif
 #endif
 
 
@@ -1311,6 +1332,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
 	}
       else
 	{
+#ifdef _LIBC
+	  int dfd = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
+		     ? -1 : dirfd ((DIR *) stream));
+#endif
 	  int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
 			   | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
 #if defined _AMIGA || defined VMS
@@ -1369,7 +1394,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
 		  /* If the file we found is a symlink we have to
 		     make sure the target file exists.  */
 		  if (!DIRENT_MIGHT_BE_SYMLINK (d)
-		      || link_exists_p (directory, dirlen, name, pglob,
+		      || link_exists_p (dfd, directory, dirlen, name, pglob,
 					flags))
 		    {
 		      if (cur == names->count)