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

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. test_lutimens

   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 lutimens(a,b) and
  20    utimensat(AT_FDCWD,a,b,AT_SYMLINK_NOFOLLOW).  FUNC is the function
  21    to test.  Assumes that BASE and ASSERT are already defined.  If
  22    PRINT, warn before skipping tests with status 77.  */
  23 static int
  24 test_lutimens (int (*func) (char const *, struct timespec const *), bool print)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26   int result;
  27   int saved_errno;
  28   struct stat st1;
  29   struct stat st2;
  30   bool atime_supported = true;
  31 
  32   /* Non-symlinks should be handled just like utimens.  */
  33   errno = 0;
  34   ASSERT (func ("no_such", NULL) == -1);
  35   ASSERT (errno == ENOENT);
  36   errno = 0;
  37   ASSERT (func ("no_such/", NULL) == -1);
  38   ASSERT (errno == ENOENT || errno == ENOTDIR);
  39   errno = 0;
  40   ASSERT (func ("", NULL) == -1);
  41   ASSERT (errno == ENOENT);
  42   ASSERT (close (creat (BASE "file", 0600)) == 0);
  43   ASSERT (stat (BASE "file", &st1) == 0);
  44   ASSERT (st1.st_atime != Y2K);
  45   ASSERT (st1.st_mtime != Y2K);
  46   {
  47     struct timespec ts[2];
  48     ts[0].tv_sec = Y2K;
  49     ts[0].tv_nsec = 0;
  50     ts[1] = ts[0];
  51     errno = 0;
  52     ASSERT (func (BASE "file/", ts) == -1);
  53     ASSERT (errno == ENOTDIR);
  54     ASSERT (stat (BASE "file", &st2) == 0);
  55     ASSERT (st1.st_atime == st2.st_atime);
  56     ASSERT (st1.st_mtime == st2.st_mtime);
  57   }
  58   {
  59     struct timespec ts[2];
  60     ts[0].tv_sec = Y2K;
  61     ts[0].tv_nsec = 0;
  62     ts[1] = ts[0];
  63     nap ();
  64     ASSERT (func (BASE "file", ts) == 0);
  65   }
  66   ASSERT (stat (BASE "file", &st2) == 0);
  67   ASSERT (st2.st_atime == Y2K);
  68   ASSERT (st2.st_mtime == Y2K);
  69   if (check_ctime)
  70     ASSERT (ctime_compare (&st1, &st2) < 0);
  71 
  72   /* Play with symlink timestamps.  */
  73   if (symlink (BASE "file", BASE "link"))
  74     {
  75       ASSERT (unlink (BASE "file") == 0);
  76       if (print)
  77         fputs ("skipping test: symlinks not supported on this file system\n",
  78                stderr);
  79       return 77;
  80     }
  81   errno = 0;
  82   result = func (BASE "link", NULL);
  83   saved_errno = errno;
  84   /* Make sure we did not reference through link by accident.  */
  85   ASSERT (stat (BASE "file", &st1) == 0);
  86   ASSERT (st1.st_atime == Y2K);
  87   ASSERT (st1.st_mtime == Y2K);
  88   ASSERT (lstat (BASE "link", &st1) == 0);
  89   ASSERT (st1.st_atime != Y2K);
  90   ASSERT (st1.st_mtime != Y2K);
  91   ASSERT (unlink (BASE "file") == 0);
  92   if (result == -1 && saved_errno == ENOSYS)
  93     {
  94       ASSERT (unlink (BASE "link") == 0);
  95       if (print)
  96         fputs ("skipping test: "
  97                "setting symlink time not supported on this file system\n",
  98                stderr);
  99       return 77;
 100     }
 101   ASSERT (!result);
 102   ASSERT (lstat (BASE "link", &st1) == 0);
 103   /* On cygwin, lstat() changes atime of symlinks, so that lutimens
 104      can only effectively modify mtime.  */
 105   nap ();
 106   ASSERT (lstat (BASE "link", &st2) == 0);
 107   if (st1.st_atime != st2.st_atime
 108       || get_stat_atime_ns (&st1) != get_stat_atime_ns (&st2))
 109     atime_supported = false;
 110   ASSERT (st1.st_ctime == st2.st_ctime);
 111   ASSERT (get_stat_ctime_ns (&st1) == get_stat_ctime_ns (&st2));
 112 
 113   /* Invalid arguments.  */
 114   {
 115     struct timespec ts[2];
 116     ts[0].tv_sec = Y2K;
 117     ts[0].tv_nsec = UTIME_BOGUS_POS;
 118     ts[1].tv_sec = Y2K;
 119     ts[1].tv_nsec = 0;
 120     errno = 0;
 121     ASSERT (func (BASE "link", ts) == -1);
 122     ASSERT (errno == EINVAL);
 123   }
 124   {
 125     struct timespec ts[2];
 126     ts[0].tv_sec = Y2K;
 127     ts[0].tv_nsec = 0;
 128     ts[1].tv_sec = Y2K;
 129     ts[1].tv_nsec = UTIME_BOGUS_NEG;
 130     errno = 0;
 131     ASSERT (func (BASE "link", ts) == -1);
 132     ASSERT (errno == EINVAL);
 133   }
 134   ASSERT (lstat (BASE "link", &st2) == 0);
 135   if (atime_supported)
 136     {
 137       ASSERT (st1.st_atime == st2.st_atime);
 138       ASSERT (get_stat_atime_ns (&st1) == get_stat_atime_ns (&st2));
 139     }
 140   ASSERT (utimecmp (BASE "link", &st1, &st2, 0) == 0);
 141 
 142   /* Set both times.  */
 143   {
 144     struct timespec ts[2];
 145     ts[0].tv_sec = Y2K;
 146     ts[0].tv_nsec = BILLION / 2 - 1;
 147     ts[1].tv_sec = Y2K;
 148     ts[1].tv_nsec = BILLION - 1;
 149     nap ();
 150     ASSERT (func (BASE "link", ts) == 0);
 151     ASSERT (lstat (BASE "link", &st2) == 0);
 152     if (atime_supported)
 153       {
 154         ASSERT (st2.st_atime == Y2K);
 155         ASSERT (0 <= get_stat_atime_ns (&st2));
 156         ASSERT (get_stat_atime_ns (&st2) < BILLION / 2);
 157       }
 158     ASSERT (st2.st_mtime == Y2K);
 159     ASSERT (0 <= get_stat_mtime_ns (&st2));
 160     ASSERT (get_stat_mtime_ns (&st2) < BILLION);
 161     if (check_ctime)
 162       ASSERT (ctime_compare (&st1, &st2) < 0);
 163   }
 164 
 165   /* Play with UTIME_OMIT, UTIME_NOW.  */
 166   {
 167     struct stat st3;
 168     struct timespec ts[2];
 169     ts[0].tv_sec = BILLION;
 170     ts[0].tv_nsec = UTIME_OMIT;
 171     ts[1].tv_sec = 0;
 172     ts[1].tv_nsec = UTIME_NOW;
 173     nap ();
 174     ASSERT (func (BASE "link", ts) == 0);
 175     ASSERT (lstat (BASE "link", &st3) == 0);
 176     if (atime_supported)
 177       {
 178         ASSERT (st3.st_atime == Y2K);
 179         ASSERT (0 <= get_stat_atime_ns (&st3));
 180         ASSERT (get_stat_atime_ns (&st3) < BILLION / 2);
 181       }
 182     ASSERT (utimecmp (BASE "link", &st1, &st3, 0) <= 0);
 183     if (check_ctime)
 184       ASSERT (ctime_compare (&st2, &st3) < 0);
 185     nap ();
 186     ts[0].tv_nsec = 0;
 187     ts[1].tv_nsec = UTIME_OMIT;
 188     ASSERT (func (BASE "link", ts) == 0);
 189     ASSERT (lstat (BASE "link", &st2) == 0);
 190     if (atime_supported)
 191       {
 192         ASSERT (st2.st_atime == BILLION);
 193         ASSERT (get_stat_atime_ns (&st2) == 0);
 194       }
 195     ASSERT (st3.st_mtime == st2.st_mtime);
 196     ASSERT (get_stat_mtime_ns (&st3) == get_stat_mtime_ns (&st2));
 197     if (check_ctime > 0)
 198       ASSERT (ctime_compare (&st3, &st2) < 0);
 199   }
 200 
 201   /* Symlink to directory.  */
 202   ASSERT (unlink (BASE "link") == 0);
 203   ASSERT (symlink (BASE "dir", BASE "link") == 0);
 204   ASSERT (mkdir (BASE "dir", 0700) == 0);
 205   {
 206     struct timespec ts[2];
 207     ts[0].tv_sec = Y2K;
 208     ts[0].tv_nsec = 0;
 209     ts[1] = ts[0];
 210     ASSERT (func (BASE "link/", ts) == 0);
 211   }
 212   /* On cygwin 1.5, stat() changes atime of directories, so only check
 213      mtime.  */
 214   ASSERT (stat (BASE "dir", &st1) == 0);
 215   ASSERT (st1.st_mtime == Y2K);
 216   ASSERT (lstat (BASE "link", &st1) == 0);
 217   ASSERT (st1.st_atime != Y2K);
 218   ASSERT (st1.st_mtime != Y2K);
 219   ASSERT (func (BASE "link", NULL) == 0);
 220   ASSERT (stat (BASE "dir", &st1) == 0);
 221   ASSERT (st1.st_mtime == Y2K);
 222   ASSERT (lstat (BASE "link", &st1) == 0);
 223   ASSERT (st1.st_atime != Y2K);
 224   ASSERT (st1.st_mtime != Y2K);
 225 
 226   /* Cleanup.  */
 227   ASSERT (rmdir (BASE "dir") == 0);
 228   ASSERT (unlink (BASE "link") == 0);
 229   return 0;
 230 }

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