diff options
author | Paul Eggert <eggert@CS.UCLA.EDU> | 2010-07-02 23:41:08 -0700 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2010-07-03 10:28:08 +0200 |
commit | efe53cc72b599979ea292754ecfe8abf7c839d22 (patch) | |
tree | 4041993405c58203ccad79280dd9aed419e06ec2 /src | |
parent | d27d6d371f3f7ede14b6bde79ddd45307d30fa47 (diff) | |
download | coreutils-efe53cc72b599979ea292754ecfe8abf7c839d22.tar.xz |
du: don't miscount duplicate directories or link-count-1 files
* NEWS: Mention this.
* src/du.c (hash_all): New static var.
(process_file): Use it.
(main): Set it.
* tests/du/hard-link: Add a couple of test cases to help make
sure this bug stays squashed.
* tests/du/files0-from: Adjust existing tests to reflect
change in semantics with duplicate arguments.
Diffstat (limited to 'src')
-rw-r--r-- | src/du.c | 15 |
1 files changed, 13 insertions, 2 deletions
@@ -132,6 +132,9 @@ static bool apparent_size = false; /* If true, count each hard link of files with multiple links. */ static bool opt_count_all = false; +/* If true, hash all files to look for hard links. */ +static bool hash_all; + /* If true, output the NUL byte instead of a newline at the end of each line. */ static bool opt_nul_terminate_output = false; @@ -518,8 +521,7 @@ process_file (FTS *fts, FTSENT *ent) via a hard link, then don't let it contribute to the sums. */ if (skip || (!opt_count_all - && ! S_ISDIR (sb->st_mode) - && 1 < sb->st_nlink + && (hash_all || (! S_ISDIR (sb->st_mode) && 1 < sb->st_nlink)) && ! hash_ins (sb->st_ino, sb->st_dev))) { /* Note that we must not simply return here. @@ -937,11 +939,20 @@ main (int argc, char **argv) quote (files_from)); ai = argv_iter_init_stream (stdin); + + /* It's not easy here to count the arguments, so assume the + worst. */ + hash_all = true; } else { char **files = (optind < argc ? argv + optind : cwd_only); ai = argv_iter_init_argv (files); + + /* Hash all dev,ino pairs if there are multiple arguments, or if + following non-command-line symlinks, because in either case a + file with just one hard link might be seen more than once. */ + hash_all = (optind + 1 < argc || symlink_deref_bits == FTS_LOGICAL); } if (!ai) |