summaryrefslogtreecommitdiff
path: root/lib/cycle-check.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2004-07-28 00:30:45 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2004-07-28 00:30:45 +0000
commit62ce2087cb983e60c4bd9bf7741b2f3e8e69b0c4 (patch)
tree085d6de87f7ba7c756653c4fda4826250d2d0c40 /lib/cycle-check.c
parent43309787ced3ec53d6cda5deaa55d75c712520cb (diff)
downloadcoreutils-62ce2087cb983e60c4bd9bf7741b2f3e8e69b0c4.tar.xz
(is_zero_or_power_of_two): Renamed from
is_power_of_two, to reflect better what it really does. All uses changed. Arg is now uintmax_t, not unsigned int (it should have been unsigned long int -- that was a bug). (cycle_check): Check for integer overflow in cycle count, and report a cycle if that happens, as it must be a cycle by this point.
Diffstat (limited to 'lib/cycle-check.c')
-rw-r--r--lib/cycle-check.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/lib/cycle-check.c b/lib/cycle-check.c
index 8c7463b2f..99a88c35e 100644
--- a/lib/cycle-check.c
+++ b/lib/cycle-check.c
@@ -1,5 +1,6 @@
/* help detect directory cycles efficiently
- Copyright 2003 Free Software Foundation, Inc.
+
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -39,8 +40,10 @@
#define CC_MAGIC 9827862
+/* Return true if I is a power of 2, or is zero. */
+
static inline bool
-is_power_of_two (unsigned int i)
+is_zero_or_power_of_two (uintmax_t i)
{
return (i & (i - 1)) == 0;
}
@@ -73,8 +76,16 @@ cycle_check (struct cycle_check_state *state, struct stat const *sb)
/* If the number of `descending' chdir calls is a power of two,
record the dev/ino of the current directory. */
- if (is_power_of_two (++(state->chdir_counter)))
+ if (is_zero_or_power_of_two (++(state->chdir_counter)))
{
+ /* On all architectures that we know about, if the counter
+ overflows then there is a directory cycle here somewhere,
+ even if we haven't detected it yet. Typically this happens
+ only after the counter is incremented 2**64 times, so it's a
+ fairly theoretical point. */
+ if (state->chdir_counter == 0)
+ return true;
+
state->dev_ino.st_dev = sb->st_dev;
state->dev_ino.st_ino = sb->st_ino;
}