From 8ba5d1a70cc88fce33fabf488f382140d4c5c101 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Wed, 4 Nov 2009 22:01:52 +0100 Subject: 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. --- src/du.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'src/du.c') 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; -- cgit v1.2.3-54-g00ecf