On 03/08/2012 10:36 AM, Jim Meyering wrote: > Jim Meyering wrote: > ... >>> du (GNU coreutils) 8.15 >> >> Oh! That's a regression. >> Thank you for finding/reporting it! >> >> Here's the fix I expect to use: >> >> diff --git a/src/du.c b/src/du.c >> index e4e36df..c1c0417 100644 >> --- a/src/du.c >> +++ b/src/du.c >> @@ -443,7 +443,9 @@ process_file (FTS *fts, FTSENT *ent) >> return false; >> } >> >> - if (fts->fts_options & FTS_XDEV && fts->fts_dev != sb->st_dev) >> + if (fts->fts_options & FTS_XDEV >> + && FTS_ROOTLEVEL < ent->fts_level >> + && fts->fts_dev != sb->st_dev) >> excluded = true; >> } > > Thanks again. > A small reproducer is to run this: > > du -x /etc/passwd > > If it prints nothing (coreutils-8.15), you have the bug. > > Here is a complete patch: > >>From b51e77776fbc4c8fa6727388b735427596595477 Mon Sep 17 00:00:00 2001 > From: Jim Meyering <[email protected]> > Date: Thu, 8 Mar 2012 10:33:50 +0100 > Subject: [PATCH] du: --one-file-system (-x) ignores non-directory arguments
I find it a bit easier to parse if the summary describes the change rather than the bug. So something like: du: fix -x to include 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. While I can `git show` the above revision format, gitk doesn't hyperlink it. Does gitweb auto link the above format? I guess they may in future at least? > --- > 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 04c911f..3224b30 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 c8dd75f..d23f7b3 100644 > --- a/THANKS.in > +++ b/THANKS.in > @@ -134,6 +134,7 @@ Dan Hagerty [email protected] > Dan Pascu [email protected] > Daniel Bergstrom [email protected] > Daniel P. Berrangé [email protected] > +Daniel Stavrovski [email protected] > Dániel Varga [email protected] > Danny Levinson [email protected] > Darrel Francis [email protected] > diff --git a/src/du.c b/src/du.c > index e4e36df..41c9535 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 f0d264a..110080f 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 Maybe this is enough? du $opt f | grep . > /dev/null || fail=1 cheers, Pádraig.
