summaryrefslogtreecommitdiff
path: root/src/du.c
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2009-11-04 22:01:52 +0100
committerJim Meyering <meyering@redhat.com>2009-11-05 08:32:31 +0100
commit8ba5d1a70cc88fce33fabf488f382140d4c5c101 (patch)
treea75c802193ea86f1a7b245981644c51a2bfd8dc0 /src/du.c
parent38cb824673a53062ab0d2ee843cdf58affc17e04 (diff)
downloadcoreutils-8ba5d1a70cc88fce33fabf488f382140d4c5c101.tar.xz
du now diagnoses cycles, rather than ignoring them
* src/du.c (symlink_deref_bits): New global, decl moved from ... (main): ...here. (process_file): When fts detects a directory cycle that can't be due to symlinks, report it and arrange to exit nonzero. * NEWS (Bug fixes): Mention it.
Diffstat (limited to 'src/du.c')
-rw-r--r--src/du.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/du.c b/src/du.c
index 9831a1788..7ef0306e8 100644
--- a/src/du.c
+++ b/src/du.c
@@ -65,9 +65,12 @@ extern bool fts_debug;
/* Initial size of the hash table. */
#define INITIAL_TABLE_SIZE 103
+/* Select one of the three FTS_ options that control if/when
+ to follow a symlink. */
+static int symlink_deref_bits = FTS_PHYSICAL;
+
/* Hash structure for inode and device numbers. The separate entry
structure makes it easier to rehash "in place". */
-
struct entry
{
ino_t st_ino;
@@ -495,6 +498,20 @@ process_file (FTS *fts, FTSENT *ent)
ok = false;
break;
+ case FTS_DC: /* directory that causes cycles */
+ /* When dereferencing no symlinks, or when dereferencing only
+ those listed on the command line and we're not processing
+ a command-line argument, then a cycle is a serious problem. */
+ if (symlink_deref_bits == FTS_PHYSICAL
+ || (symlink_deref_bits == (FTS_COMFOLLOW | FTS_PHYSICAL)
+ && ent->fts_level != FTS_ROOTLEVEL))
+ {
+ emit_cycle_warning (ent->fts_path);
+ return false;
+ }
+ ok = true;
+ break;
+
default:
ok = true;
break;
@@ -661,10 +678,6 @@ main (int argc, char **argv)
/* Bit flags that control how fts works. */
int bit_flags = FTS_TIGHT_CYCLE_CHECK | FTS_DEFER_STAT;
- /* Select one of the three FTS_ options that control if/when
- to follow a symlink. */
- int symlink_deref_bits = FTS_PHYSICAL;
-
/* If true, display only a total for each argument. */
bool opt_summarize_only = false;