]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
du: fix -x: don't ignore non-directory arguments
authorJim Meyering <meyering@redhat.com>
Thu, 8 Mar 2012 09:33:50 +0000 (10:33 +0100)
committerJim Meyering <meyering@redhat.com>
Thu, 8 Mar 2012 12:04:09 +0000 (13:04 +0100)
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
THANKS.in
src/du.c
tests/du/one-file-system

diff --git a/NEWS b/NEWS
index 04c911fbd0872fe21141837980e63cd4001b21ed..3224b30079c3a92aacf2d73ffddbfc7ff58e10f8 100644 (file)
--- 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
index c8dd75f85c84573f9ade6b4f8a32a578f73c7fbd..d23f7b3b9ed98d3f1eb04b7300316f5b6d8c4747 100644 (file)
--- 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
index e4e36dfead3e5ffbdf8262e29480bbdf6848f90b..41c9535410056dd61771c40cfd958ffc6d1cb35d 100644 (file)
--- 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;
         }
 
index f0d264ae2893df8f8e23ccdf01eebd4ad592e313..110080f0296b3ed71d4a4ec10e16b63065bf720a 100755 (executable)
@@ -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