]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Fix tests/ckmtime.c arithmetic
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 30 Jul 2024 15:35:59 +0000 (08:35 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 4 Aug 2024 08:41:43 +0000 (01:41 -0700)
* 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.

tests/ckmtime.c

index cd4c2fe62fd35003b1b8d27d847d6fbb3c4ccd51..04a1b6c9836aa4f2561f8766eb11791357e9f8f7 100644 (file)
@@ -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
 #include <stat-time.h>
 #include <timespec.h>
 
-#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;