(root)/
glibc-2.38/
support/
support_path_support_time64.c
       1  /* Check if path supports 64-bit time interfaces.
       2     Copyright (C) 2021-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <fcntl.h>
      20  #include <unistd.h>
      21  #include <support/check.h>
      22  #include <support/support.h>
      23  #include <sys/stat.h>
      24  #ifdef __linux__
      25  #include <sysdep.h>
      26  #endif
      27  
      28  #ifdef __linux__
      29  static int
      30  utimesat_call (const char *path, const struct __timespec64 tsp[2])
      31  {
      32  # ifndef __NR_utimensat_time64
      33  #  define __NR_utimensat_time64 __NR_utimensat
      34  # endif
      35    return syscall (__NR_utimensat_time64, AT_FDCWD, path, &tsp[0], 0);
      36  }
      37  #endif
      38  
      39  bool
      40  support_path_support_time64_value (const char *path, int64_t at, int64_t mt)
      41  {
      42  #ifdef __linux__
      43    /* Obtain the original timestamps to restore at the end.  */
      44    struct statx ostx;
      45    TEST_VERIFY_EXIT (statx (AT_FDCWD, path, 0, STATX_BASIC_STATS, &ostx) == 0);
      46  
      47    const struct __timespec64 tsp[] = { { at, 0 }, { mt, 0 } };
      48  
      49    /* Return is kernel does not support __NR_utimensat_time64.  */
      50    if (utimesat_call (path, tsp) == -1)
      51      return false;
      52  
      53    /* Verify if the last access and last modification time match the ones
      54       obtained with statx.  */
      55    struct statx stx;
      56    TEST_VERIFY_EXIT (statx (AT_FDCWD, path, 0, STATX_BASIC_STATS, &stx) == 0);
      57  
      58    bool support = stx.stx_atime.tv_sec == tsp[0].tv_sec
      59  		 && stx.stx_mtime.tv_sec == tsp[1].tv_sec;
      60  
      61    /* Reset to original timestamps.  */
      62    const struct __timespec64 otsp[] =
      63    {
      64      { ostx.stx_atime.tv_sec, ostx.stx_atime.tv_nsec },
      65      { ostx.stx_mtime.tv_sec, ostx.stx_mtime.tv_nsec },
      66    };
      67    TEST_VERIFY_EXIT (utimesat_call (path, otsp) == 0);
      68  
      69    return support;
      70  #else
      71    return true;
      72  #endif
      73  }