1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-02-11 01:42:17 +02:00

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.
This commit is contained in:
Paul Eggert
2021-08-11 11:16:05 -07:00
parent a574283c7a
commit a3c04f8da1
2 changed files with 28 additions and 9 deletions

3
NEWS
View File

@@ -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]

View File

@@ -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);
}
}
}