diff options
| author | Paul Eggert <eggert@cs.ucla.edu> | 2021-08-11 11:16:05 -0700 |
|---|---|---|
| committer | Paul Eggert <eggert@cs.ucla.edu> | 2021-08-11 11:22:40 -0700 |
| commit | a3c04f8da14f0fe2a0561bf5562032b8ce5dafa9 (patch) | |
| tree | 261005ed8e9463709e3caa9933f1284f8bb0a5e6 | |
| parent | cat: with -E fix handling of \r\n spanning buffers (diff) | |
| download | coreutils-a3c04f8da14f0fe2a0561bf5562032b8ce5dafa9.tar.gz coreutils-a3c04f8da14f0fe2a0561bf5562032b8ce5dafa9.zip | |
df: fix bug with automounted
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.
| -rw-r--r-- | NEWS | 3 | ||||
| -rw-r--r-- | src/df.c | 34 |
2 files changed, 28 insertions, 9 deletions
@@ -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] @@ -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); - } } } |
