From f7f398a1d91ca6b09e5282423711a7c785be2789 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Thu, 8 Mar 2012 10:33:50 +0100 Subject: du: fix -x: don't ignore non-directory arguments Surprise! "du -x non-DIR" would print nothing. Note that the problem arises only when processing a non-directory specified on the command line. Not surprisingly, "du -x" still works as expected for any directory argument. When performing its same-file-system check, du may skip an entry only if it is at fts_level 1 or greater. Command-line arguments are at fts_level == 0 (FTS_ROOTLEVEL). * src/du.c (process_file): Don't use the top-level FTS->fts_dev when testing for --one-file-system (-x). It happens to be valid for directories, but it is always 0 for a non-directory. * tests/du/one-file-system: Add tests for this. * NEWS (Bug fixes): Mention it. Reported by Daniel Stavrovski in http://bugs.gnu.org/10967. Introduced by commit v8.14-95-gcfe1040. --- NEWS | 4 ++++ THANKS.in | 1 + src/du.c | 9 ++++++++- tests/du/one-file-system | 10 +++++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 04c911fbd..3224b3007 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,10 @@ GNU coreutils NEWS -*- outline -*- ** Bug fixes + du --one-file-system (-x) would ignore any non-directory specified on + the command line. For example, "touch f; du -x f" would print nothing. + [bug introduced in coreutils-8.14] + mv now lets you move a symlink onto a same-inode destination file that has two or more hard links. Before, it would reject that, saying that they are the same, implicitly warning you that the move would result in diff --git a/THANKS.in b/THANKS.in index c8dd75f85..d23f7b3b9 100644 --- a/THANKS.in +++ b/THANKS.in @@ -134,6 +134,7 @@ Dan Hagerty hag@gnu.ai.it.edu Dan Pascu dan@services.iiruc.ro Daniel Bergstrom noa@melody.se Daniel P. Berrangé berrange@redhat.com +Daniel Stavrovski d@stavrovski.net Dániel Varga danielv@axelero.hu Danny Levinson danny.levinson@overture.com Darrel Francis d.francis@cheerful.com diff --git a/src/du.c b/src/du.c index e4e36dfea..41c953541 100644 --- a/src/du.c +++ b/src/du.c @@ -443,7 +443,14 @@ process_file (FTS *fts, FTSENT *ent) return false; } - if (fts->fts_options & FTS_XDEV && fts->fts_dev != sb->st_dev) + /* The --one-file-system (-x) option cannot exclude anything + specified on the command-line. By definition, it can exclude + a file or directory only when its device number is different + from that of its just-processed parent directory, and du does + not process the parent of a command-line argument. */ + if (fts->fts_options & FTS_XDEV + && FTS_ROOTLEVEL < ent->fts_level + && fts->fts_dev != sb->st_dev) excluded = true; } diff --git a/tests/du/one-file-system b/tests/du/one-file-system index f0d264ae2..110080f02 100755 --- a/tests/du/one-file-system +++ b/tests/du/one-file-system @@ -43,7 +43,15 @@ compare exp out || fail=1 du -xL d > u || fail=1 sed 's/^[0-9][0-9]* //' u > out1 echo d > exp1 || fail=1 - compare exp1 out1 || fail=1 +# With coreutils-8.15, "du -xs FILE" would print no output. +touch f +for opt in -x -xs; do + du $opt f > u || fail=1 + sed 's/^[0-9][0-9]* //' u > out2 + echo f > exp2 || fail=1 + compare exp2 out2 || fail=1 +done + Exit $fail -- cgit v1.2.3-54-g00ecf