unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Speed up realpath and fix EOVERFLOW bug
@ 2020-02-19 21:03 Paul Eggert
  0 siblings, 0 replies; only message in thread
From: Paul Eggert @ 2020-02-19 21:03 UTC (permalink / raw)
  To: libc-alpha; +Cc: Paul Eggert

[BZ#24970]
* stdlib/canonicalize.c: Do not include <sys/stat.h>; no longer needed.
(__realpath): Use __readlink instead of __lxstat64 to determine
whether RPATH is a symbolic link.  This avoids an unnecessary
__lxstat64 when RPATH is a symbolic link and replaces __lxstat64
with __readlink when RPATH is not a symbolic link.  It also avoids
an unnecessary failure if __lxstat64 would fail with errno ==
EOVERFLOW due to timestamp or other integer overflow.  Remove
unnecessary S_ISDIR check, as the next time through the loop will
fail with errno == ENOTDIR as appropriate.
---
 stdlib/canonicalize.c | 28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index cbd885a3c5..cd2051d35f 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -21,7 +21,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <limits.h>
-#include <sys/stat.h>
 #include <errno.h>
 #include <stddef.h>
 
@@ -98,9 +97,10 @@ __realpath (const char *name, char *resolved)
       dest = rpath + 1;
     }
 
+  char *buf = __alloca (path_max);
+
   for (start = end = name; *start; start = end)
     {
-      struct stat64 st;
       int n;
 
       /* Skip sequence of multiple path-separators.  */
@@ -158,12 +158,14 @@ __realpath (const char *name, char *resolved)
 	  dest = __mempcpy (dest, start, end - start);
 	  *dest = '\0';
 
-	  if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
-	    goto error;
-
-	  if (S_ISLNK (st.st_mode))
+	  n = __readlink (rpath, buf, path_max);
+	  if (n < 0)
+	    {
+	      if (errno != EINVAL)
+		goto error;
+	    }
+	  else
 	    {
-	      char *buf = __alloca (path_max);
 	      size_t len;
 
 	      if (++num_links > __eloop_threshold ())
@@ -172,11 +174,6 @@ __realpath (const char *name, char *resolved)
 		  goto error;
 		}
 
-	      n = __readlink (rpath, buf, path_max - 1);
-	      if (n < 0)
-		goto error;
-	      buf[n] = '\0';
-
 	      if (!extra_buf)
 		extra_buf = __alloca (path_max);
 
@@ -187,6 +184,8 @@ __realpath (const char *name, char *resolved)
 		  goto error;
 		}
 
+	      buf[n] = '\0';
+
 	      /* Careful here, end may be a pointer into extra_buf... */
 	      memmove (&extra_buf[n], end, len + 1);
 	      name = end = memcpy (extra_buf, buf, n);
@@ -198,11 +197,6 @@ __realpath (const char *name, char *resolved)
 		if (dest > rpath + 1)
 		  while ((--dest)[-1] != '/');
 	    }
-	  else if (!S_ISDIR (st.st_mode) && *end != '\0')
-	    {
-	      __set_errno (ENOTDIR);
-	      goto error;
-	    }
 	}
     }
   if (dest > rpath + 1 && dest[-1] == '/')
-- 
2.24.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-02-19 21:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-19 21:03 [PATCH] Speed up realpath and fix EOVERFLOW bug Paul Eggert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).