From: Pádraig Brady
Date: Sun, 29 Oct 2017 22:29:05 +0000 (-0700) Subject: df: fix hang with fifo argument X-Git-Tag: v8.29~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b04ce61958c1f1fc264950f8d3b6058f640ee491;p=thirdparty%2Fcoreutils.git df: fix hang with fifo argument * 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 --- diff --git a/NEWS b/NEWS index 806e3efd68..3e6704d5c7 100644 --- 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] diff --git a/src/df.c b/src/df.c index 7345bc9aa8..d9a26e0649 100644 --- 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); + } } } diff --git a/tests/df/unreadable.sh b/tests/df/unreadable.sh index c28cdc9576..fb4c91c343 100755 --- a/tests/df/unreadable.sh +++ b/tests/df/unreadable.sh @@ -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