]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
df: fix bug with automounted
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 11 Aug 2021 18:16:05 +0000 (11:16 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 11 Aug 2021 18:22:40 +0000 (11:22 -0700)
If the command-line argument is automounted, df would use
stat info that became wrong after the following open.
* NEWS: Mention the fix (bug#50012).
* src/df.c (automount_stat_err): New function.
This fixes the hang on fifos in a better way, by using O_NONBLOCK.
(main): Use it.

NEWS
src/df.c

diff --git a/NEWS b/NEWS
index 49ee083e41d38600077b91f88604ccaadb6734ba..e14de1397ec07e8746f1e330a46f82514f8279c2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   df no longer outputs duplicate remote mounts in the presence of bind mounts.
   [bug introduced in coreutils-8.26]
 
+  df no longer mishandles command-line args that it pre-mounts
+  [bug introduced in coreutils-8.29]
+
   du no longer crashes on XFS file systems when the directory hierarchy is
   heavily changed during the run.
   [bug introduced in coreutils-8.25]
index 4534935f56d55163f4fd0ac2e5d25607902bd551..48025b9fcac3b3f2992e35f25b97dae595cc6272 100644 (file)
--- a/src/df.c
+++ b/src/df.c
@@ -276,6 +276,28 @@ static struct option const long_options[] =
   {NULL, 0, NULL, 0}
 };
 
+/* Stat FILE and put the results into *ST.  Return 0 if successful, an
+   error number otherwise.  Try to open FILE before statting, to
+   trigger automounts.  */
+
+static int
+automount_stat_err (char const *file, struct stat *st)
+{
+  int fd = open (file, O_RDONLY | O_NOCTTY | O_NONBLOCK);
+  if (fd < 0)
+    {
+      if (errno == ENOENT || errno == ENOTDIR)
+        return errno;
+      return stat (file, st) == 0 ? 0 : errno;
+    }
+  else
+    {
+      int err = fstat (fd, st) == 0 ? 0 : errno;
+      close (fd);
+      return err;
+    }
+}
+
 /* Replace problematic chars with '?'.
    Since only control characters are currently considered,
    this should work in all encodings.  */
@@ -1772,19 +1794,13 @@ main (int argc, char **argv)
       stats = xnmalloc (argc - optind, sizeof *stats);
       for (int i = optind; i < argc; ++i)
         {
-          if (stat (argv[i], &stats[i - optind]))
+          int err = automount_stat_err (argv[i], &stats[i - optind]);
+          if (err != 0)
             {
-              error (0, errno, "%s", quotef (argv[i]));
+              error (0, err, "%s", quotef (argv[i]));
               exit_status = EXIT_FAILURE;
               argv[i] = NULL;
             }
-          else if (! S_ISFIFO (stats[i - optind].st_mode))
-            {
-              /* open() is needed to automount in some cases.  */
-              int fd = open (argv[i], O_RDONLY | O_NOCTTY);
-              if (0 <= fd)
-                close (fd);
-            }
         }
     }