[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Findutils-patches] [PATCH] Fix Savannah bug #22056, -Xtime tests are of
From: |
James Youngman |
Subject: |
[Findutils-patches] [PATCH] Fix Savannah bug #22056, -Xtime tests are off by one second. |
Date: |
Sat, 9 Feb 2008 15:22:25 +0000 |
2008-02-09 James Youngman <address@hidden>
Fix Savannah bug #22056, -Xtime tests are off by one second.
* find/defs.h (struct options): Change cur_day_start from time_t
to strct timespec.
* find/util.c (set_option_defaults): Likewise.
* find/parser.c (get_relative_timestamp): Change the origin
argument from time_t to struct timespec.
(estimate_timestamp_success_rate): Ignore the nanoseconds field of
the timestamp when estimating the probable success rate.
(parse_daystart): Handle the nanoseconds field too.
(do_parse_xmin): The origin argument to get_relative_timestamp()
is of type struct timespec, not time_t.
(parse_used): Likewise.
(parse_time): Likewise.
* find/testsuite/Makefile.am (EXTRA_DIST_EXP): Added test for
-mtime 0; find.posix/mtime0.{exp,xo}.
* NEWS: mention this bugfix.
Signed-off-by: James Youngman <address@hidden>
---
NEWS | 3 ++
find/defs.h | 5 +--
find/parser.c | 61 +++++++++++++++++++++-------------
find/testsuite/Makefile.am | 1 +
find/testsuite/find.posix/mtime0.exp | 10 +++++
find/testsuite/find.posix/mtime0.xo | 1 +
find/util.c | 5 ++-
7 files changed, 59 insertions(+), 27 deletions(-)
create mode 100644 find/testsuite/find.posix/mtime0.exp
create mode 100644 find/testsuite/find.posix/mtime0.xo
diff --git a/NEWS b/NEWS
index d947f64..e139d3c 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ GNU findutils NEWS - User visible changes. -*- outline -*-
(allout)
atomically, instead of just claiming the rename is atomic in a
comment.
+#22056: -Xtime tests are off by one second (e.g. rm -f x; touch x;
+find x -mtime 0 should print x).
+
#21960: xargs should collect the exit status of child processes even if
the total count of unreaped children has not yet reached the maximum
allowed.
diff --git a/find/defs.h b/find/defs.h
index c3e330b..d076aa9 100644
--- a/find/defs.h
+++ b/find/defs.h
@@ -571,9 +571,8 @@ struct options
struct timespec start_time; /* Time at start of execution.
*/
- /* Seconds between 00:00 1/1/70 and either one day before now
- (the default), or the start of today (if -daystart is given). */
- time_t cur_day_start;
+ /* Either one day before now (the default), or the start of today (if
-daystart is given). */
+ struct timespec cur_day_start;
/* If true, cur_day_start has been adjusted to the start of the day. */
boolean full_days;
diff --git a/find/parser.c b/find/parser.c
index 7eaefc1..b7ef88f 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -185,7 +185,7 @@ static boolean get_comp_type PARAMS((const char **str,
enum comparison_type *comp_type));
static boolean get_relative_timestamp PARAMS((const char *str,
struct time_val *tval,
- time_t origin,
+ struct timespec origin,
double sec_per_unit,
const char *overflowmessage));
static boolean get_num PARAMS((const char *str,
@@ -613,7 +613,11 @@ estimate_file_age_success_rate(float num_days)
static float
estimate_timestamp_success_rate(time_t when)
{
- int num_days = (options.cur_day_start - when) / 86400;
+ /* This calculation ignores the nanoseconds field of the
+ * origin, but I don't think that makes much difference
+ * to our estimate.
+ */
+ int num_days = (options.cur_day_start.tv_sec - when) / 86400;
return estimate_file_age_success_rate(num_days);
}
@@ -764,12 +768,13 @@ parse_daystart (const struct parser_table* entry, char
**argv, int *arg_ptr)
if (options.full_days == false)
{
- options.cur_day_start += DAYSECS;
- local = localtime (&options.cur_day_start);
- options.cur_day_start -= (local
- ? (local->tm_sec + local->tm_min * 60
- + local->tm_hour * 3600)
- : options.cur_day_start % DAYSECS);
+ options.cur_day_start.tv_sec += DAYSECS;
+ options.cur_day_start.tv_nsec = 0;
+ local = localtime (&options.cur_day_start.tv_sec);
+ options.cur_day_start.tv_sec -= (local
+ ? (local->tm_sec + local->tm_min * 60
+ + local->tm_hour * 3600)
+ : options.cur_day_start.tv_sec %
DAYSECS);
options.full_days = true;
}
return true;
@@ -1381,8 +1386,9 @@ do_parse_xmin (const struct parser_table* entry,
{
struct time_val tval;
tval.xval = xv;
- if (get_relative_timestamp(minutes, &tval,
- options.cur_day_start + DAYSECS, 60,
+ struct timespec origin = options.cur_day_start;
+ origin.tv_sec += DAYSECS;
+ if (get_relative_timestamp(minutes, &tval, origin, 60,
"arithmetic overflow while converting %s "
"minutes to a number of seconds"))
{
@@ -2397,7 +2403,8 @@ parse_used (const struct parser_table* entry, char
**argv, int *arg_ptr)
if (collect_arg(argv, arg_ptr, &offset_str))
{
/* The timespec is actually a delta value, so we use an origin of 0. */
- if (get_relative_timestamp(offset_str, &tval, 0, DAYSECS, errmsg))
+ struct timespec zero = {0,0};
+ if (get_relative_timestamp(offset_str, &tval, zero, DAYSECS, errmsg))
{
our_pred = insert_primary (entry);
our_pred->args.reftime = tval;
@@ -3223,12 +3230,12 @@ insert_exec_ok (const char *action,
static boolean
get_relative_timestamp (const char *str,
struct time_val *result,
- time_t origin,
+ struct timespec origin,
double sec_per_unit,
const char *overflowmessage)
{
uintmax_t checkval;
- double offset, seconds, f;
+ double offset, seconds, nanosec;
if (get_comp_type(&str, &result->kind))
{
@@ -3245,15 +3252,23 @@ get_relative_timestamp (const char *str,
{
/* Separate the floating point number the user specified
* (which is a number of days, or minutes, etc) into an
- * integral number of seconds (SECONDS) and a fraction (F).
+ * integral number of seconds (SECONDS) and a fraction (NANOSEC).
*/
- f = modf(offset * sec_per_unit, &seconds);
+ nanosec = modf(offset * sec_per_unit, &seconds);
+ nanosec *= 1.0e9; /* convert from fractional seconds to ns. */
- result->ts.tv_sec = origin - seconds;
- result->ts.tv_nsec = fabs(f * 1e9);
-
+ result->ts.tv_sec = origin.tv_sec - seconds;
+ result->ts.tv_nsec = origin.tv_nsec - nanosec;
+ checkval = (uintmax_t)origin.tv_sec - seconds;
+
+ if (origin.tv_nsec < nanosec)
+ {
+ /* Perform a carry operation */
+ result->ts.tv_nsec += 1000000000;
+ result->ts.tv_sec -= 1;
+ checkval -= 1;
+ }
/* Check for overflow. */
- checkval = (uintmax_t)origin - seconds;
if (checkval != result->ts.tv_sec)
{
/* an overflow has occurred. */
@@ -3294,7 +3309,7 @@ parse_time (const struct parser_table* entry, char
*argv[], int *arg_ptr)
const char *timearg, *orig_timearg;
const char *errmsg = "arithmetic overflow while converting %s "
"days to a number of seconds";
- time_t origin;
+ struct timespec origin;
if (!collect_arg(argv, arg_ptr, &timearg))
return false;
@@ -3310,9 +3325,9 @@ parse_time (const struct parser_table* entry, char
*argv[], int *arg_ptr)
*/
if (COMP_LT == comp)
{
- uintmax_t expected = origin + (DAYSECS-1);
- origin += (DAYSECS-1);
- if (origin != expected)
+ uintmax_t expected = origin.tv_sec + (DAYSECS-1);
+ origin.tv_sec += (DAYSECS-1);
+ if (origin.tv_sec != expected)
{
error(1, 0,
_("arithmetic overflow when trying to calculate the end of
today"));
diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am
index 3712f0c..0f98e0c 100644
--- a/find/testsuite/Makefile.am
+++ b/find/testsuite/Makefile.am
@@ -190,6 +190,7 @@ find.posix/grouping.exp \
find.posix/group-empty.exp \
find.posix/group-missing.exp \
find.posix/links.exp \
+find.posix/mtime0.exp \
find.posix/sv-bug-11175.exp \
find.posix/sv-bug-12181.exp \
find.posix/depth1.exp \
diff --git a/find/testsuite/find.posix/mtime0.exp
b/find/testsuite/find.posix/mtime0.exp
new file mode 100644
index 0000000..23237a1
--- /dev/null
+++ b/find/testsuite/find.posix/mtime0.exp
@@ -0,0 +1,10 @@
+## Test for find . -mtime 0
+## This detects Savannah bug #22056, -Xtime tests are off by one second
+
+exec rm -rf tmp
+exec mkdir tmp
+# Touch the file in the setup phase, to make sure its mtime is as
+# recent as possible.
+proc prep {} { exec touch tmp/x }
+find_start p { tmp -type f -mtime 0 } "" "" prep
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/mtime0.xo
b/find/testsuite/find.posix/mtime0.xo
new file mode 100644
index 0000000..74c14ef
--- /dev/null
+++ b/find/testsuite/find.posix/mtime0.xo
@@ -0,0 +1 @@
+tmp/x
diff --git a/find/util.c b/find/util.c
index f057f5d..40f36d5 100644
--- a/find/util.c
+++ b/find/util.c
@@ -925,8 +925,11 @@ set_option_defaults(struct options *p)
p->do_dir_first = true;
p->explicit_depth = false;
p->maxdepth = p->mindepth = -1;
+
p->start_time = now();
- p->cur_day_start = p->start_time.tv_sec - DAYSECS;
+ p->cur_day_start.tv_sec = p->start_time.tv_sec - DAYSECS;
+ p->cur_day_start.tv_nsec = p->start_time.tv_nsec;
+
p->full_days = false;
p->stay_on_filesystem = false;
p->ignore_readdir_race = false;
--
1.5.3.8
- [Findutils-patches] [PATCH] Fix Savannah bug #22056, -Xtime tests are off by one second.,
James Youngman <=