[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#10967: Weird 'du' behavior. Bug in coreutils-8.15 ?
From: |
Pádraig Brady |
Subject: |
bug#10967: Weird 'du' behavior. Bug in coreutils-8.15 ? |
Date: |
Thu, 08 Mar 2012 11:04:38 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:6.0) Gecko/20110816 Thunderbird/6.0 |
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 <address@hidden>
> 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 address@hidden
> Dan Pascu address@hidden
> Daniel Bergstrom address@hidden
> Daniel P. Berrangé address@hidden
> +Daniel Stavrovski address@hidden
> Dániel Varga address@hidden
> Danny Levinson address@hidden
> Darrel Francis address@hidden
> 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.