(root)/
tar-1.35/
tests/
ckmtime.c
       1  /* Check if filesystem timestamps are consistent with the system time.
       2     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       3        
       4     This program is free software; you can redistribute it and/or modify it
       5     under the terms of the GNU General Public License as published by the
       6     Free Software Foundation; either version 3, or (at your option) any later
       7     version.
       8  
       9     This program is distributed in the hope that it will be useful, but
      10     WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
      12     Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License along
      15     with this program.  If not, see <http://www.gnu.org/licenses/>.
      16  */
      17  #include <config.h>
      18  #include <sys/stat.h>
      19  #include <sys/time.h>
      20  #include <unistd.h>
      21  #include <string.h>
      22  #include <assert.h>
      23  #include <stdio.h>
      24  #include <stdlib.h>
      25  #include <stat-time.h>
      26  #include <timespec.h>
      27  
      28  #define TEMPLATE "ckmtime.XXXXXX"
      29  #define BILLION 1000000000
      30  
      31  /* Some filesystems can slightly offset the timestamps of newly created files.
      32     To compensate for it, tar testsuite waits at least 1 second before creating
      33     next level of incremental backups.
      34  
      35     However, NFS mounts can offset the timestamps by bigger amounts.  
      36     
      37     This program returns with success (0) if a newly created file is assigned
      38     mtime matching the system time to the nearest second.
      39  */
      40  int
      41  main (int argc, char **argv)
      42  {
      43    int fd;
      44    char name[sizeof(TEMPLATE)];
      45    struct stat st;
      46    struct timespec ts, td;
      47    double diff;
      48    
      49    gettime (&ts);
      50    
      51    strcpy (name, TEMPLATE);
      52    umask (077);
      53    fd = mkstemp (name);
      54    assert (fd != -1);
      55    unlink (name);
      56    assert (fstat (fd, &st) == 0);
      57    close (fd);
      58  
      59    td = timespec_sub (get_stat_mtime (&st), ts);
      60    diff = td.tv_sec * BILLION + td.tv_nsec;
      61    if (diff < 0)
      62      diff = - diff;
      63    if (diff / BILLION >= 1)
      64      {
      65        fprintf (stderr, "file timestamp unreliable\n");
      66        return 1;
      67      }
      68    return 0;
      69  }