]> Savannah Git Hosting - gnulib.git/commitdiff
stat failing with EOVERFLOW implies existence
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 24 Dec 2020 19:38:48 +0000 (11:38 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 24 Dec 2020 20:06:48 +0000 (12:06 -0800)
* lib/euidaccess.c (euidaccess):
* lib/file-has-acl.c (file_has_acl):
* lib/link.c (link, rpl_link):
* lib/mkdir.c (rpl_mkdir):
* lib/mkfifo.c (rpl_mkfifo):
* lib/mknod.c (rpl_mknod):
* lib/ptsname_r.c (__ptsname_r):
* lib/symlink.c (rpl_symlink):
* lib/symlinkat.c (rpl_symlinkat):
* lib/unlink.c (rpl_unlink):
* lib/unlinkat.c (rpl_unlinkat):
* lib/utime.c (utime):
If stat fails with EOVERFLOW the file exists, so treat it that way
in file-existence tests that do not need struct stat values.

13 files changed:
ChangeLog
lib/euidaccess.c
lib/file-has-acl.c
lib/link.c
lib/mkdir.c
lib/mkfifo.c
lib/mknod.c
lib/ptsname_r.c
lib/symlink.c
lib/symlinkat.c
lib/unlink.c
lib/unlinkat.c
lib/utime.c

index b0cad381a149949435e01f71b247c59ae0a10c66..3d2186fb914fe41886df41e93dab63a4495d2041 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2020-12-24  Paul Eggert  <eggert@cs.ucla.edu>
 
+       stat failing with EOVERFLOW implies existence
+       * lib/euidaccess.c (euidaccess):
+       * lib/file-has-acl.c (file_has_acl):
+       * lib/link.c (link, rpl_link):
+       * lib/mkdir.c (rpl_mkdir):
+       * lib/mkfifo.c (rpl_mkfifo):
+       * lib/mknod.c (rpl_mknod):
+       * lib/ptsname_r.c (__ptsname_r):
+       * lib/symlink.c (rpl_symlink):
+       * lib/symlinkat.c (rpl_symlinkat):
+       * lib/unlink.c (rpl_unlink):
+       * lib/unlinkat.c (rpl_unlinkat):
+       * lib/utime.c (utime):
+       If stat fails with EOVERFLOW the file exists, so treat it that way
+       in file-existence tests that do not need struct stat values.
+
        canonicalize-lgpl: remove freea macro
        * lib/canonicalize-lgpl.c (freea) [_LIBC]: Remove; not needed.
 
index b352123ae1804072721a25d54f5cb7ae61fdf234..a32e3366eb8fb8376d129986cbcdf43ed88ede28 100644 (file)
@@ -107,7 +107,10 @@ euidaccess (const char *file, int mode)
      safe.  */
 
   if (mode == F_OK)
-    return stat (file, &stats);
+    {
+      int result = stat (file, &stats);
+      return result != 0 && errno == EOVERFLOW ? 0 : result;
+    }
   else
     {
       int result;
@@ -142,8 +145,8 @@ euidaccess (const char *file, int mode)
     /* If we are not set-uid or set-gid, access does the same.  */
     return access (file, mode);
 
-  if (stat (file, &stats) != 0)
-    return -1;
+  if (stat (file, &stats) == -1)
+    return mode == F_OK && errno == EOVERFLOW ? 0 : -1;
 
   /* The super-user can read and write any file, and execute any file
      that anyone can execute.  */
index c667ae9d24a7ebd07cc86267f0e7800575363cae..4adb7f6f1e30507c08c18947fc0b26981f3c9536 100644 (file)
@@ -353,7 +353,7 @@ file_has_acl (char const *name, struct stat const *sb)
             {
               struct stat statbuf;
 
-              if (stat (name, &statbuf) < 0)
+              if (stat (name, &statbuf) == -1 && errno != EOVERFLOW)
                 return -1;
 
               return acl_nontrivial (count, entries);
index 797cdf8b9b3362467bc650104d424b9dd60c7998..3c0c341d54cf2e64838a2dc75daa91e9e8c0ca91 100644 (file)
@@ -107,7 +107,7 @@ link (const char *file1, const char *file2)
     char *p = strchr (dir, '\0');
     while (dir < p && (*--p != '/' && *p != '\\'));
     *p = '\0';
-    if (p != dir && stat (dir, &st) == -1)
+    if (p != dir && stat (dir, &st) != 0 && errno != EOVERFLOW)
       {
         int saved_errno = errno;
         free (dir);
@@ -181,7 +181,7 @@ rpl_link (char const *file1, char const *file2)
   struct stat st;
 
   /* Don't allow IRIX to dereference dangling file2 symlink.  */
-  if (!lstat (file2, &st))
+  if (lstat (file2, &st) == 0 || errno == EOVERFLOW)
     {
       errno = EEXIST;
       return -1;
@@ -218,7 +218,7 @@ rpl_link (char const *file1, char const *file2)
       if (p)
         {
           *p = '\0';
-          if (stat (dir, &st) == -1)
+          if (stat (dir, &st) != 0 && errno != EOVERFLOW)
             {
               int saved_errno = errno;
               free (dir);
index c0d4b616513f217d61bea1363aeaf2fd1fca02c7..386344fcd2649d3ed9d92d72a62df029b441155d 100644 (file)
@@ -77,7 +77,7 @@ rpl_mkdir (char const *dir, mode_t mode maybe_unused)
                          || (last[1] == '.' && last[2] == '\0')))
       {
         struct stat st;
-        if (stat (tmp_dir, &st) == 0)
+        if (stat (tmp_dir, &st) == 0 || errno == EOVERFLOW)
           errno = EEXIST;
         return -1;
       }
index 706297c0a9bd796a1c9e60e02733b69737c363b2..952ffc0fe445a128586619823dcedc3efab1ee26 100644 (file)
@@ -48,7 +48,7 @@ rpl_mkfifo (char const *name, mode_t mode)
   if (len && name[len - 1] == '/')
     {
       struct stat st;
-      if (stat (name, &st) == 0)
+      if (stat (name, &st) == 0 || errno == EOVERFLOW)
         errno = EEXIST;
       return -1;
     }
index 4e778fa15eb473c516826a755da0b0c42e495493..1de2794c6c5bf1bb140ee8352bfb7340a01d7305 100644 (file)
@@ -56,7 +56,7 @@ rpl_mknod (char const *name, mode_t mode, dev_t dev)
       if (len && name[len - 1] == '/')
         {
           struct stat st;
-          if (stat (name, &st) == 0)
+          if (stat (name, &st) == 0 || errno == EOVERFLOW)
             errno = EEXIST;
           return -1;
         }
index 12b8e66f0a59e4b1dc009d14ab77d725d42c422d..99d1701dc7994e5e1c57595d577bc840d3bd392d 100644 (file)
@@ -198,7 +198,7 @@ __ptsname_r (int fd, char *buf, size_t buflen)
     buf[sizeof (_PATH_DEV) - 1] = 't';
 # endif
 
-  if (__stat (buf, &st) < 0)
+  if (__stat (buf, &st) < 0 && errno != EOVERFLOW)
     return errno;
 
   __set_errno (save_errno);
index e7dbd184a99e6e4ada3021640c2c001a064b7ae8..b1196b9ee85178258fd578c0ae0e56e85e30041b 100644 (file)
@@ -36,7 +36,7 @@ rpl_symlink (char const *contents, char const *name)
   if (len && name[len - 1] == '/')
     {
       struct stat st;
-      if (lstat (name, &st) == 0)
+      if (lstat (name, &st) == 0 || errno == EOVERFLOW)
         errno = EEXIST;
       return -1;
     }
index 5ce2fc9d5cc687325c45ac5e3224621c8a98c2f0..2e0ff9a799a923b78185a8c9f28de04697ca02be 100644 (file)
@@ -38,7 +38,7 @@ rpl_symlinkat (char const *contents, int fd, char const *name)
   if (len && name[len - 1] == '/')
     {
       struct stat st;
-      if (fstatat (fd, name, &st, 0) == 0)
+      if (fstatat (fd, name, &st, 0) == 0 || errno == EOVERFLOW)
         errno = EEXIST;
       return -1;
     }
index ba5f6269c3ac0269ec68ae353aecead5b2f0b538..58b1e900171c1d5b0a89f1cf3796bb20a61d1349 100644 (file)
@@ -63,7 +63,7 @@ rpl_unlink (char const *name)
          can't delete a directory via a symlink.  */
       struct stat st;
       result = lstat (name, &st);
-      if (result == 0)
+      if (result == 0 || errno == EOVERFLOW)
         {
           /* Trailing NUL will overwrite the trailing slash.  */
           char *short_name = malloc (len);
@@ -79,6 +79,7 @@ rpl_unlink (char const *name)
               return -1;
             }
           free (short_name);
+          result = 0;
         }
     }
   if (!result)
index 442368641ade27055c97ea55881733a76b485d8a..02ac851eea6c36cae31e5dd744094fd56260e4c0 100644 (file)
@@ -59,7 +59,7 @@ rpl_unlinkat (int fd, char const *name, int flag)
          directory.  */
       struct stat st;
       result = lstatat (fd, name, &st);
-      if (result == 0)
+      if (result == 0 || errno == EOVERFLOW)
         {
           /* Trailing NUL will overwrite the trailing slash.  */
           char *short_name = malloc (len);
@@ -78,6 +78,7 @@ rpl_unlinkat (int fd, char const *name, int flag)
               return -1;
             }
           free (short_name);
+          result = 0;
         }
     }
   if (!result)
index 6de8adbb375b79923ed5b1d2d4c0fa5e2522b7f9..bf7d7c534a0c3e3da700e908586a5faf1733487e 100644 (file)
@@ -276,7 +276,7 @@ utime (const char *name, const struct utimbuf *ts)
     {
       struct stat buf;
 
-      if (stat (name, &buf) < 0)
+      if (stat (name, &buf) == -1 && errno != EOVERFLOW)
         return -1;
     }
 # endif /* REPLACE_FUNC_UTIME_FILE */