root/maint/gnulib/tests/test-futimens.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. test_futimens

   1 /* Test of file timestamp modification functions.
   2    Copyright (C) 2009-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 #include "test-utimens-common.h"
  18 
  19 /* This file is designed to test both fdutimens(a,NULL,b) and
  20    futimens(a,b).  FUNC is the function to test.  Assumes that BASE
  21    and ASSERT are already defined.  If PRINT, warn before skipping
  22    tests with status 77.  */
  23 static int
  24 test_futimens (int (*func) (int, struct timespec const *),
     /* [previous][next][first][last][top][bottom][index][help] */
  25                bool print)
  26 {
  27   int fd = creat (BASE "file", 0600);
  28   int result;
  29   struct stat st1;
  30   struct stat st2;
  31   ASSERT (0 <= fd);
  32 
  33   /* Sanity check.  */
  34   ASSERT (fstat (fd, &st1) == 0);
  35   nap ();
  36   errno = 0;
  37   result = func (fd, NULL);
  38   if (result == -1 && errno == ENOSYS)
  39     {
  40       ASSERT (close (fd) == 0);
  41       ASSERT (unlink (BASE "file") == 0);
  42       if (print)
  43         fputs ("skipping test: "
  44                "setting fd time not supported on this file system\n",
  45                stderr);
  46       return 77;
  47     }
  48   ASSERT (!result);
  49   ASSERT (fstat (fd, &st2) == 0);
  50   /* If utimens truncates to worse resolution than the file system
  51      supports, then time can appear to go backwards between now and a
  52      follow-up utimens with UTIME_NOW or a NULL timespec.  Use
  53      UTIMECMP_TRUNCATE_SOURCE to compensate, with st1 as the
  54      source.  */
  55   ASSERT (0 <= utimecmp (BASE "file", &st2, &st1, UTIMECMP_TRUNCATE_SOURCE));
  56   if (check_ctime)
  57     ASSERT (ctime_compare (&st1, &st2) < 0);
  58   {
  59     /* On some NFS systems, the 'now' timestamp of creat or a NULL
  60        timespec is determined by the server, but the 'now' timestamp
  61        determined by gettime() (as is done when using UTIME_NOW) is
  62        determined by the client; since the two machines are not
  63        necessarily on the same clock, this is another case where time
  64        can appear to go backwards.  The rest of this test cares about
  65        client time, so manually use gettime() to set both times.  */
  66     struct timespec ts[2];
  67     gettime (&ts[0]);
  68     ts[1] = ts[0];
  69     ASSERT (func (fd, ts) == 0);
  70     ASSERT (fstat (fd, &st1) == 0);
  71     nap ();
  72   }
  73 
  74   /* Invalid arguments.  */
  75   {
  76     errno = 0;
  77     ASSERT (func (AT_FDCWD, NULL) == -1);
  78     ASSERT (errno == EBADF);
  79   }
  80   {
  81     errno = 0;
  82     ASSERT (func (-1, NULL) == -1);
  83     ASSERT (errno == EBADF);
  84   }
  85   {
  86     close (99);
  87     errno = 0;
  88     ASSERT (func (99, NULL) == -1);
  89     ASSERT (errno == EBADF);
  90   }
  91   {
  92     int fd0 = dup (0);
  93     ASSERT (0 <= fd0);
  94     ASSERT (close (fd0) == 0);
  95     errno = 0;
  96     ASSERT (func (fd0, NULL) == -1);
  97     ASSERT (errno == EBADF);
  98   }
  99   {
 100     struct timespec ts[2];
 101     ts[0].tv_sec = Y2K;
 102     ts[0].tv_nsec = UTIME_BOGUS_POS;
 103     ts[1].tv_sec = Y2K;
 104     ts[1].tv_nsec = 0;
 105     errno = 0;
 106     ASSERT (func (fd, ts) == -1);
 107     ASSERT (errno == EINVAL);
 108   }
 109   {
 110     struct timespec ts[2];
 111     ts[0].tv_sec = Y2K;
 112     ts[0].tv_nsec = 0;
 113     ts[1].tv_sec = Y2K;
 114     ts[1].tv_nsec = UTIME_BOGUS_NEG;
 115     errno = 0;
 116     ASSERT (func (fd, ts) == -1);
 117     ASSERT (errno == EINVAL);
 118   }
 119   ASSERT (fstat (fd, &st2) == 0);
 120   ASSERT (st1.st_atime == st2.st_atime);
 121   ASSERT (get_stat_atime_ns (&st1) == get_stat_atime_ns (&st2));
 122   ASSERT (utimecmp (BASE "file", &st1, &st2, 0) == 0);
 123 
 124   /* Set both times.  */
 125   {
 126     struct timespec ts[2];
 127     ts[0].tv_sec = Y2K;
 128     ts[0].tv_nsec = BILLION / 2 - 1;
 129     ts[1].tv_sec = Y2K;
 130     ts[1].tv_nsec = BILLION - 1;
 131     ASSERT (func (fd, ts) == 0);
 132     ASSERT (fstat (fd, &st2) == 0);
 133     ASSERT (st2.st_atime == Y2K);
 134     ASSERT (0 <= get_stat_atime_ns (&st2));
 135     ASSERT (get_stat_atime_ns (&st2) < BILLION / 2);
 136     ASSERT (st2.st_mtime == Y2K);
 137     ASSERT (0 <= get_stat_mtime_ns (&st2));
 138     ASSERT (get_stat_mtime_ns (&st2) < BILLION);
 139     if (check_ctime)
 140       ASSERT (ctime_compare (&st1, &st2) < 0);
 141   }
 142 
 143   /* Play with UTIME_OMIT, UTIME_NOW.  */
 144   {
 145     struct stat st3;
 146     struct timespec ts[2];
 147     ts[0].tv_sec = BILLION;
 148     ts[0].tv_nsec = UTIME_OMIT;
 149     ts[1].tv_sec = 0;
 150     ts[1].tv_nsec = UTIME_NOW;
 151     nap ();
 152     ASSERT (func (fd, ts) == 0);
 153     ASSERT (fstat (fd, &st3) == 0);
 154     ASSERT (st3.st_atime == Y2K);
 155     ASSERT (0 <= get_stat_atime_ns (&st3));
 156     ASSERT (get_stat_atime_ns (&st3) <= BILLION / 2);
 157     ASSERT (utimecmp (BASE "file", &st1, &st3, UTIMECMP_TRUNCATE_SOURCE) <= 0);
 158     if (check_ctime)
 159       ASSERT (ctime_compare (&st2, &st3) < 0);
 160     nap ();
 161     ts[0].tv_nsec = 0;
 162     ts[1].tv_nsec = UTIME_OMIT;
 163     ASSERT (func (fd, ts) == 0);
 164     ASSERT (fstat (fd, &st2) == 0);
 165     ASSERT (st2.st_atime == BILLION);
 166     ASSERT (get_stat_atime_ns (&st2) == 0);
 167     ASSERT (st3.st_mtime == st2.st_mtime);
 168     ASSERT (get_stat_mtime_ns (&st3) == get_stat_mtime_ns (&st2));
 169     if (check_ctime > 0)
 170       ASSERT (ctime_compare (&st3, &st2) < 0);
 171   }
 172 
 173   /* Cleanup.  */
 174   ASSERT (close (fd) == 0);
 175   ASSERT (unlink (BASE "file") == 0);
 176   return 0;
 177 }

/* [previous][next][first][last][top][bottom][index][help] */