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.
This commit is contained in:
Jim Meyering
2009-11-04 22:01:52 +01:00
parent 38cb824673
commit 8ba5d1a70c
2 changed files with 21 additions and 5 deletions

3
NEWS
View File

@@ -8,6 +8,9 @@ GNU coreutils NEWS -*- outline -*-
Even then, chcon may still be useful.
[bug introduced in coreutils-8.0]
du now diagnoses an ostensible directory cycle and arranges to exit nonzero.
Before, it would silently ignore the offending directory and all "contents."
env -u A=B now fails, rather than silently adding A to the
environment. Likewise, printenv A=B silently ignores the invalid
name. [the bugs date back to the initial implementation]

View File

@@ -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;