From: Paul Eggert Date: Tue, 30 Jul 2024 15:35:59 +0000 (-0700) Subject: Fix tests/ckmtime.c arithmetic X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=dcc90722ac885d6e5cd0b4ba59ae9f3666a873c3;p=thirdparty%2Ftar.git Fix tests/ckmtime.c arithmetic * tests/ckmtime.c (main): Don’t assume time_t is signed. Avoid integer overflows (quite possible if time_t is 32 bit). Do calculations precisely, without any rounding errors. --- diff --git a/tests/ckmtime.c b/tests/ckmtime.c index cd4c2fe6..04a1b6c9 100644 --- a/tests/ckmtime.c +++ b/tests/ckmtime.c @@ -1,6 +1,6 @@ /* Check if filesystem timestamps are consistent with the system time. Copyright (C) 2016-2024 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 the Free Software Foundation; either version 3, or (at your option) any later @@ -25,42 +25,35 @@ #include #include -#define TEMPLATE "ckmtime.XXXXXX" -#define BILLION 1000000000 - /* Some filesystems can slightly offset the timestamps of newly created files. To compensate for it, tar testsuite waits at least 1 second before creating next level of incremental backups. - However, NFS mounts can offset the timestamps by bigger amounts. - + However, NFS mounts can offset the timestamps by bigger amounts. + This program returns with success (0) if a newly created file is assigned mtime matching the system time to the nearest second. */ int main (int argc, char **argv) { - int fd; - char name[sizeof(TEMPLATE)]; - struct stat st; - struct timespec ts, td; - double diff; - - gettime (&ts); - - strcpy (name, TEMPLATE); + struct timespec s = current_timespec (); + umask (077); - fd = mkstemp (name); - assert (fd != -1); + char name[] = "ckmtime.XXXXXX"; + int fd = mkstemp (name); + assert (0 <= fd); unlink (name); - assert (fstat (fd, &st) == 0); - close (fd); + struct stat st; + int r = fstat (fd, &st); + assert (0 <= r); + r = close (fd); + assert (0 <= r); - td = timespec_sub (get_stat_mtime (&st), ts); - diff = td.tv_sec * BILLION + td.tv_nsec; - if (diff < 0) - diff = - diff; - if (diff / BILLION >= 1) + struct timespec + t = get_stat_mtime (&st), + d = timespec_cmp (s, t) < 0 ? timespec_sub (t, s) : timespec_sub (s, t); + if (timespec_cmp (make_timespec (1, 0), d) < 0) { fprintf (stderr, "file timestamp unreliable\n"); return 1;