(root)/
strace-6.5/
tests/
utimensat.c
       1  /*
       2   * Check decoding of utimensat syscall.
       3   *
       4   * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2015-2023 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include <fcntl.h>
      13  #include <stdint.h>
      14  #include <stdio.h>
      15  #include <sys/stat.h>
      16  #include <sys/time.h>
      17  #include <unistd.h>
      18  #include "scno.h"
      19  
      20  #if defined __NR_utimensat && defined UTIME_NOW && defined UTIME_OMIT
      21  
      22  # if SIZEOF_KERNEL_LONG_T == 4
      23  #  define big_tv_sec "-559038737"
      24  #  define huge_tv_sec "-559038737"
      25  # else
      26  #  define big_tv_sec "3735928559"
      27  #  define huge_tv_sec "-3819351491602432273"
      28  # endif
      29  
      30  # if XLAT_RAW
      31  #  define str_at_fdcwd			"-100"
      32  #  define str_at_symlink_nofollow	"0x100"
      33  #  define str_at_removedir		"0x200"
      34  #  define str_flags1			"0x600"
      35  #  define str_flags2			"0xffffffff"
      36  #  define str_utime_now_omit \
      37  	"[{tv_sec=" big_tv_sec ", tv_nsec=1073741823}, " \
      38  	"{tv_sec=" huge_tv_sec ", tv_nsec=1073741822}]"
      39  # elif XLAT_VERBOSE
      40  #  define str_at_fdcwd			"-100 /* AT_FDCWD */"
      41  #  define str_at_symlink_nofollow	"0x100 /* AT_SYMLINK_NOFOLLOW */"
      42  #  define str_at_removedir		"0x200 /* AT_REMOVEDIR */"
      43  #  define str_flags1 \
      44  	"0x600 /* AT_REMOVEDIR|AT_SYMLINK_FOLLOW */"
      45  #  define str_flags2 \
      46  	"0xffffffff /* AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW" \
      47  	"|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|AT_RECURSIVE|0xffff60ff */"
      48  #  define str_utime_now_omit \
      49  	"[{tv_sec=" big_tv_sec ", tv_nsec=1073741823} /* UTIME_NOW */, " \
      50  	"{tv_sec=" huge_tv_sec ", tv_nsec=1073741822} /* UTIME_OMIT */]"
      51  # else
      52  #  define str_at_fdcwd			"AT_FDCWD"
      53  #  define str_at_symlink_nofollow	"AT_SYMLINK_NOFOLLOW"
      54  #  define str_at_removedir		"AT_REMOVEDIR"
      55  #  define str_flags1			"AT_REMOVEDIR|AT_SYMLINK_FOLLOW"
      56  #  define str_flags2 \
      57  	"AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW" \
      58  	"|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|AT_RECURSIVE|0xffff60ff"
      59  #  define str_utime_now_omit		"[UTIME_NOW, UTIME_OMIT]"
      60  # endif
      61  
      62  static void
      63  print_ts(const kernel_old_timespec_t *ts)
      64  {
      65  	printf("{tv_sec=%lld, tv_nsec=%llu}", (long long) ts->tv_sec,
      66  		zero_extend_signed_to_ull(ts->tv_nsec));
      67  	print_time_t_nsec(ts->tv_sec,
      68  			  zero_extend_signed_to_ull(ts->tv_nsec), 1);
      69  }
      70  
      71  static const char *errstr;
      72  
      73  static long
      74  k_utimensat(const kernel_ulong_t dirfd,
      75  	    const kernel_ulong_t pathname,
      76  	    const kernel_ulong_t times,
      77  	    const kernel_ulong_t flags)
      78  {
      79  	long rc = syscall(__NR_utimensat, dirfd, pathname, times, flags);
      80  	errstr = sprintrc(rc);
      81  	return rc;
      82  }
      83  
      84  int
      85  main(void)
      86  {
      87  	static const kernel_ulong_t bogus_fd =
      88  		(kernel_ulong_t) 0xbadc0deddeadbeef;
      89  	static const kernel_ulong_t kfdcwd =
      90  		(kernel_ulong_t) 0xdefaced00000000 | -100U;
      91  	static const char proto_fname[] = "utimensat\nfilename";
      92  	static const char qname[] = "\"utimensat\\nfilename\"";
      93  
      94  	char *const fname = tail_memdup(proto_fname, sizeof(proto_fname));
      95  	const kernel_ulong_t kfname = (uintptr_t) fname;
      96  	kernel_old_timespec_t *const ts = tail_alloc(sizeof(*ts) * 2);
      97  
      98  	(void) close(0);
      99  
     100  	/* dirfd */
     101  	k_utimensat(0, kfname, 0, 0);
     102  	printf("utimensat(0, %s, NULL, 0) = %s\n", qname, errstr);
     103  
     104  	k_utimensat(bogus_fd, kfname, 0, 0);
     105  	printf("utimensat(%d, %s, NULL, 0) = %s\n",
     106  	       (int) bogus_fd, qname, errstr);
     107  
     108  	k_utimensat(-100U, kfname, 0, 0);
     109  	printf("utimensat(" str_at_fdcwd ", %s, NULL, 0) = %s\n", qname, errstr);
     110  
     111  	k_utimensat(kfdcwd, kfname, 0, 0);
     112  	printf("utimensat(" str_at_fdcwd ", %s, NULL, 0) = %s\n", qname, errstr);
     113  
     114  	/* pathname */
     115  	k_utimensat(kfdcwd, 0, 0, 0);
     116  	printf("utimensat(" str_at_fdcwd ", NULL, NULL, 0) = %s\n", errstr);
     117  
     118  	k_utimensat(kfdcwd, kfname + sizeof(proto_fname) - 1, 0, 0);
     119  	printf("utimensat(" str_at_fdcwd ", \"\", NULL, 0) = %s\n", errstr);
     120  
     121  	fname[sizeof(proto_fname) - 1] = '+';
     122  	k_utimensat(kfdcwd, kfname, 0, 0);
     123  	fname[sizeof(proto_fname) - 1] = '\0';
     124  	printf("utimensat(" str_at_fdcwd ", %p, NULL, 0) = %s\n", fname, errstr);
     125  
     126  	if (F8ILL_KULONG_SUPPORTED) {
     127  		k_utimensat(kfdcwd, f8ill_ptr_to_kulong(fname), 0, 0);
     128  		printf("utimensat(" str_at_fdcwd ", %#jx, NULL, 0) = %s\n",
     129  		       (uintmax_t) f8ill_ptr_to_kulong(fname), errstr);
     130  	}
     131  
     132  	/* times */
     133  	k_utimensat(kfdcwd, kfname, (uintptr_t) (ts + 1), 0);
     134  	printf("utimensat(" str_at_fdcwd ", %s, %p, 0) = %s\n",
     135  	       qname, ts + 1, errstr);
     136  
     137  	k_utimensat(kfdcwd, kfname, (uintptr_t) (ts + 2), 0);
     138  	printf("utimensat(" str_at_fdcwd ", %s, %p, 0)"
     139  	       " = %s\n", qname, ts + 2, errstr);
     140  
     141  	ts[0].tv_sec = 1492358706;
     142  	ts[0].tv_nsec = 123456789;
     143  	ts[1].tv_sec = 1492357068;
     144  	ts[1].tv_nsec = 234567890;
     145  
     146  	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
     147  	printf("utimensat(" str_at_fdcwd ", %s, [", qname);
     148  	print_ts(&ts[0]);
     149  	printf(", ");
     150  	print_ts(&ts[1]);
     151  	printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
     152  
     153  	ts[0].tv_sec = -1;
     154  	ts[0].tv_nsec = 2000000000;
     155  	ts[1].tv_sec = (typeof(ts[1].tv_sec)) -0x100000001LL;
     156  	ts[1].tv_nsec = 2345678900U;
     157  
     158  	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
     159  	printf("utimensat(" str_at_fdcwd ", %s, [", qname);
     160  	print_ts(&ts[0]);
     161  	printf(", ");
     162  	print_ts(&ts[1]);
     163  	printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
     164  
     165  	ts[0].tv_sec = 0;
     166  	ts[0].tv_nsec = 0;
     167  	ts[1].tv_sec = (typeof(ts[1].tv_sec)) 0xcafef00ddeadbeefLL;
     168  	ts[1].tv_nsec = 0;
     169  
     170  	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
     171  	printf("utimensat(" str_at_fdcwd ", %s, [", qname);
     172  	print_ts(&ts[0]);
     173  	printf(", ");
     174  	print_ts(&ts[1]);
     175  	printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
     176  
     177  	ts[0].tv_sec = 0xdeadbeefU;
     178  	ts[0].tv_nsec = 0xfacefeedU;
     179  	ts[1].tv_sec = (typeof(ts[1].tv_sec)) 0xcafef00ddeadbeefLL;
     180  	ts[1].tv_nsec = (long) 0xbadc0dedfacefeedLL;
     181  
     182  	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
     183  	printf("utimensat(" str_at_fdcwd ", %s, [", qname);
     184  	print_ts(&ts[0]);
     185  	printf(", ");
     186  	print_ts(&ts[1]);
     187  	printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
     188  
     189  	ts[0].tv_nsec = UTIME_NOW;
     190  	ts[1].tv_nsec = UTIME_OMIT;
     191  	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
     192  	printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
     193  	       ", " str_at_symlink_nofollow ") = %s\n", qname, errstr);
     194  
     195  	if (F8ILL_KULONG_SUPPORTED) {
     196  		k_utimensat(kfdcwd, kfname, f8ill_ptr_to_kulong(ts), 0);
     197  		printf("utimensat(" str_at_fdcwd ", %s, %#jx, 0) = %s\n",
     198  		       qname, (uintmax_t) f8ill_ptr_to_kulong(ts), errstr);
     199  	}
     200  
     201  	/* flags */
     202  	k_utimensat(kfdcwd, kfname, (uintptr_t) ts,
     203  		    (kernel_ulong_t) 0xdefaced00000200);
     204  	printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
     205  	       ", " str_at_removedir ") = %s\n",
     206  	       qname, errstr);
     207  
     208  	k_utimensat(kfdcwd, kfname, (uintptr_t) ts,
     209  		    (kernel_ulong_t) 0xdefaced00000600);
     210  	printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
     211  	       ", " str_flags1 ") = %s\n",
     212  	       qname, errstr);
     213  
     214  	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, (kernel_ulong_t) -1ULL);
     215  	printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
     216  	       ", " str_flags2 ") = %s\n",
     217  	       qname, errstr);
     218  
     219  	puts("+++ exited with 0 +++");
     220  	return 0;
     221  }
     222  
     223  #else
     224  
     225  SKIP_MAIN_UNDEFINED("__NR_utimensat && UTIME_NOW && UTIME_OMIT")
     226  
     227  #endif