ckmtime.c 2.0 KB

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