]> Savannah Git Hosting - gnulib.git/commitdiff
Don't interpret EOVERFLOW to mean nonexistence
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 30 Jul 2017 20:06:41 +0000 (13:06 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 30 Jul 2017 20:07:48 +0000 (13:07 -0700)
* lib/fts.c (fts_stat): If lstat fails, report its errno, which
may be EOVERFLOW; this is likely more useful than reporting the
stat errno.
* lib/glob.c (link_stat): Rename from link_exists2_p and
return -1/0 instead of 0/1.  Caller changed.
* lib/glob.c (link_exists_p):
* lib/renameat2.c (rename_noreplace, renameat2):
* lib/tempname.c (try_nocreate):
If errno == EOVERFLOW then the directory entry exists, so do not
act as if it does not exist.

ChangeLog
lib/canonicalize-lgpl.c
lib/fts.c
lib/glob.c
lib/renameat2.c
lib/tempname.c

index a6909f6e0f6d753ce9ad192a602dea397207d92d..5ef4b1d5837fef25e1b2cf7a01faf7c25ab2b8e2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2017-07-30  Paul Eggert  <eggert@cs.ucla.edu>
 
+       Don't interpret EOVERFLOW to mean nonexistence
+       * lib/fts.c (fts_stat): If lstat fails, report its errno, which
+       may be EOVERFLOW; this is likely more useful than reporting the
+       stat errno.
+       * lib/glob.c (link_stat): Rename from link_exists2_p and
+       return -1/0 instead of 0/1.  Caller changed.
+       * lib/glob.c (link_exists_p):
+       * lib/renameat2.c (rename_noreplace, renameat2):
+       * lib/tempname.c (try_nocreate):
+       If errno == EOVERFLOW then the directory entry exists, so do not
+       act as if it does not exist.
+
        backup-rename: new module
        It is like backupfile, except it avoids some race conditions,
        and it does not output to stderr or exit.
index 34b3711b2c1f0e49da434825fe2cd857a9b2838a..f76ea4c104af449590548f9a2dbcdd3084a229d7 100644 (file)
@@ -270,6 +270,8 @@ __realpath (const char *name, char *resolved)
 #endif
           *dest = '\0';
 
+          /* FIXME: if lstat fails with errno == EOVERFILE,
+             the entry exists.  */
 #ifdef _LIBC
           if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
 #else
index 790f71c463293ad58ba215f4c30a248d34138e72..a870054f3439a530d0e825906751c3f163d2be59 100644 (file)
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -1813,7 +1813,6 @@ internal_function
 fts_stat(FTS *sp, register FTSENT *p, bool follow)
 {
         struct stat *sbp = p->fts_statp;
-        int saved_errno;
 
         if (p->fts_level == FTS_ROOTLEVEL && ISSET(FTS_COMFOLLOW))
                 follow = true;
@@ -1825,13 +1824,12 @@ fts_stat(FTS *sp, register FTSENT *p, bool follow)
          */
         if (ISSET(FTS_LOGICAL) || follow) {
                 if (stat(p->fts_accpath, sbp)) {
-                        saved_errno = errno;
                         if (errno == ENOENT
                             && lstat(p->fts_accpath, sbp) == 0) {
                                 __set_errno (0);
                                 return (FTS_SLNONE);
                         }
-                        p->fts_errno = saved_errno;
+                        p->fts_errno = errno;
                         goto err;
                 }
         } else if (fstatat(sp->fts_cwd_fd, p->fts_accpath, sbp,
index 3b3194ade2b3d192e047209a904f007773913282..d0610179926bd50e09fb0bdce0d5992a76b317ab 100644 (file)
@@ -1531,12 +1531,12 @@ weak_alias (__glob_pattern_p, glob_pattern_p)
    allocated with alloca to be recycled.  */
 static int
 __attribute_noinline__
-link_exists2_p (const char *dir, size_t dirlen, const char *fname,
-               glob_t *pglob
+link_stat (const char *dir, size_t dirlen, const char *fname,
+           glob_t *pglob
 # if !defined _LIBC && !HAVE_FSTATAT
-                , int flags
+           , int flags
 # endif
-                )
+           )
 {
   size_t fnamelen = strlen (fname);
   char *fullname = __alloca (dirlen + 1 + fnamelen + 1);
@@ -1549,10 +1549,10 @@ link_exists2_p (const char *dir, size_t dirlen, const char *fname,
   if (__builtin_expect ((flags & GLOB_ALTDIRFUNC) == 0, 1))
     {
       struct_stat64 st64;
-      return __stat64 (fullname, &st64) == 0;
+      return __stat64 (fullname, &st64);
     }
 # endif
-  return (*pglob->gl_stat) (fullname, &st) == 0;
+  return (*pglob->gl_stat) (fullname, &st);
 }
 
 /* Return true if DIR/FNAME exists.  */
@@ -1560,19 +1560,21 @@ static int
 link_exists_p (int dfd, const char *dir, size_t dirlen, const char *fname,
                glob_t *pglob, int flags)
 {
+  int status;
 # if defined _LIBC || HAVE_FSTATAT
   if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
-    return link_exists2_p (dir, dirlen, fname, pglob);
+    status = link_stat (dir, dirlen, fname, pglob);
   else
     {
       /* dfd cannot be -1 here, because dirfd never returns -1 on
          glibc, or on hosts that have fstatat.  */
       struct_stat64 st64;
-      return __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0) == 0;
+      status = __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0);
     }
 # else
-  return link_exists2_p (dir, dirlen, fname, pglob, flags);
+  status = link_stat (dir, dirlen, fname, pglob, flags);
 # endif
+  return status == 0 || errno == EOVERFLOW;
 }
 #endif /* !defined GLOB_ONLY_P */
 
@@ -1643,9 +1645,11 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
       mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
                         "/", 1),
                pattern, patlen + 1);
-      if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
-           ? (*pglob->gl_stat) (fullname, &ust.st)
-           : __stat64 (fullname, &ust.st64)) == 0)
+      if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
+            ? (*pglob->gl_stat) (fullname, &ust.st)
+            : __stat64 (fullname, &ust.st64))
+           == 0)
+          || errno == EOVERFLOW)
         /* We found this file to be existing.  Now tell the rest
            of the function to copy this name into the result.  */
         flags |= GLOB_NOCHECK;
index 4f9e3d11d2950e8b94ffbce72bab6acdcab07eb0..60b721c4031a99982f5cfc42f0321742ac21abbd 100644 (file)
@@ -53,7 +53,7 @@ rename_noreplace (char const *src, char const *dst)
 {
   /* This has a race between the call to lstat and the call to rename.  */
   struct stat st;
-  return (lstat (dst, &st) == 0 ? errno_fail (EEXIST)
+  return (lstat (dst, &st) == 0 || errno == EOVERFLOW ? errno_fail (EEXIST)
           : errno == ENOENT ? rename (src, dst)
           : -1);
 }
@@ -103,7 +103,7 @@ renameat2 (int fd1, char const *src, int fd2, char const *dst,
         {
           /* This has a race between the call to lstatat and the calls to
              renameat below.  */
-          if (lstatat (fd2, dst, &dst_st) == 0)
+          if (lstatat (fd2, dst, &dst_st) == 0 || errno == EOVERFLOW)
             return errno_fail (EEXIST);
           if (errno != ENOENT)
             return -1;
index 2cd90328bdaf35603192ea69bc63459f23bb6aa9..9c4a3c2a54dea17ff28142dafecd2133e5d870a2 100644 (file)
@@ -279,7 +279,7 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
 {
   struct_stat64 st;
 
-  if (__lxstat64 (_STAT_VER, tmpl, &st) == 0)
+  if (__lxstat64 (_STAT_VER, tmpl, &st) == 0 || errno == EOVERFLOW)
     __set_errno (EEXIST);
   return errno == ENOENT ? 0 : -1;
 }