]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
df: fix hang with fifo argument
authorPádraig Brady <P@draigBrady.com>
Sun, 29 Oct 2017 22:29:05 +0000 (15:29 -0700)
committerPádraig Brady <P@draigBrady.com>
Mon, 30 Oct 2017 16:47:43 +0000 (09:47 -0700)
* src/df.c (main): stat() before open(), and avoid
the optional open when given a fifo argument.
* tests/df/unreadable.sh: Add a test case.
* NEWS: Mention the fix.
Fixes https://bugs.gnu.org/29038

NEWS
src/df.c
tests/df/unreadable.sh

diff --git a/NEWS b/NEWS
index 806e3efd681877a9a10b223ce1f4742fcecf5b69..3e6704d5c72538afc8c69442ea3c97ed80730ecc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   invalidated.  [bug introduced for "direct" in coreutils-7.5,
   and with the "nocache" implementation in coreutils-8.11]
 
+  df no longer hangs when given a fifo argument.
+  [bug introduced in coreutils-7.3]
+
   ptx -S no longer infloops for a pattern which returns zero-length matches.
   [the bug dates back to the initial implementation]
 
index 7345bc9aa8df7674790c2013b40fcc40fffaf12b..d9a26e06492661f5ac5a94f58493761e793d3f3c 100644 (file)
--- a/src/df.c
+++ b/src/df.c
@@ -1702,24 +1702,25 @@ main (int argc, char **argv)
 
   if (optind < argc)
     {
-      /* Open each of the given entries to make sure any corresponding
+      /* stat each of the given entries to make sure any corresponding
          partition is automounted.  This must be done before reading the
          file system table.  */
       stats = xnmalloc (argc - optind, sizeof *stats);
       for (int i = optind; i < argc; ++i)
         {
-          /* Prefer to open with O_NOCTTY and use fstat, but fall back
-             on using "stat", in case the file is unreadable.  */
-          int fd = open (argv[i], O_RDONLY | O_NOCTTY);
-          if ((fd < 0 || fstat (fd, &stats[i - optind]))
-              && stat (argv[i], &stats[i - optind]))
+          if (stat (argv[i], &stats[i - optind]))
             {
               error (0, errno, "%s", quotef (argv[i]));
               exit_status = EXIT_FAILURE;
               argv[i] = NULL;
             }
-          if (0 <= fd)
-            close (fd);
+          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);
+            }
         }
     }
 
index c28cdc9576eb5d78e01428a6fa77a749e86752ee..fb4c91c343086f0b2909dafa66140ba058e3c980 100755 (executable)
@@ -24,6 +24,9 @@ touch unreadable || fail=1
 chmod a-r unreadable || fail=1
 df unreadable || fail=1
 
+mkfifo_or_skip_ fifo
+timeout 10 df fifo || fail=1
+
 test "$fail" = 1 && dump_mount_list_
 
 Exit $fail