(root)/
strace-6.5/
tests/
nanosleep.c
       1  /*
       2   * Check decoding of nanosleep syscall.
       3   *
       4   * Copyright (c) 2015-2016 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 "scno.h"
      13  
      14  #ifdef __NR_nanosleep
      15  
      16  # include <assert.h>
      17  # include <stdio.h>
      18  # include <stdint.h>
      19  # include <signal.h>
      20  # include <sys/time.h>
      21  # include <unistd.h>
      22  
      23  # include "kernel_old_timespec.h"
      24  
      25  static const char *errstr;
      26  
      27  static long
      28  k_nanosleep(const void *const req, void *const rem)
      29  {
      30  	const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
      31  	const kernel_ulong_t arg1 = (uintptr_t) req;
      32  	const kernel_ulong_t arg2 = (uintptr_t) rem;
      33  	const long rc = syscall(__NR_nanosleep, arg1, arg2, bad, bad, bad, bad);
      34  	errstr = sprintrc(rc);
      35  	return rc;
      36  }
      37  
      38  static void
      39  handler(int signo)
      40  {
      41  }
      42  
      43  int
      44  main(void)
      45  {
      46  	struct {
      47  		kernel_old_timespec_t ts;
      48  		uint32_t pad[2];
      49  	} req = {
      50  		.ts.tv_nsec = 0xc0de1,
      51  		.pad = { 0xdeadbeef, 0xbadc0ded }
      52  	}, rem = {
      53  		.ts = { .tv_sec = 0xc0de2, .tv_nsec = 0xc0de3 },
      54  		.pad = { 0xdeadbeef, 0xbadc0ded }
      55  	};
      56  	const sigset_t set = {};
      57  	const struct sigaction act = { .sa_handler = handler };
      58  	const struct itimerval itv = { .it_value.tv_usec = 111111 };
      59  
      60  	if (k_nanosleep(&req.ts, NULL))
      61  		perror_msg_and_fail("nanosleep");
      62  	printf("nanosleep({tv_sec=%lld, tv_nsec=%llu}, NULL) = 0\n",
      63  	       (long long) req.ts.tv_sec,
      64  	       zero_extend_signed_to_ull(req.ts.tv_nsec));
      65  
      66  	assert(k_nanosleep(NULL, &rem.ts) == -1);
      67  	printf("nanosleep(NULL, %p) = %s\n", &rem.ts, errstr);
      68  
      69  	if (k_nanosleep(&req.ts, &rem.ts))
      70  		perror_msg_and_fail("nanosleep");
      71  	printf("nanosleep({tv_sec=%lld, tv_nsec=%llu}, %p) = 0\n",
      72  	       (long long) req.ts.tv_sec,
      73  	       zero_extend_signed_to_ull(req.ts.tv_nsec), &rem.ts);
      74  
      75  	req.ts.tv_nsec = 1000000000;
      76  	assert(k_nanosleep(&req.ts, &rem.ts) == -1);
      77  	printf("nanosleep({tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
      78  	       (long long) req.ts.tv_sec,
      79  	       zero_extend_signed_to_ull(req.ts.tv_nsec), &rem.ts,
      80  	       errstr);
      81  
      82  	req.ts.tv_sec = 0xdeadbeefU;
      83  	req.ts.tv_nsec = 0xfacefeedU;
      84  	assert(k_nanosleep(&req.ts, &rem.ts) == -1);
      85  	printf("nanosleep({tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
      86  	       (long long) req.ts.tv_sec,
      87  	       zero_extend_signed_to_ull(req.ts.tv_nsec), &rem.ts,
      88  	       errstr);
      89  
      90  	req.ts.tv_sec = (typeof(req.ts.tv_sec)) 0xcafef00ddeadbeefLL;
      91  	req.ts.tv_nsec = (long) 0xbadc0dedfacefeedLL;
      92  	assert(k_nanosleep(&req.ts, &rem.ts) == -1);
      93  	printf("nanosleep({tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
      94  	       (long long) req.ts.tv_sec,
      95  	       zero_extend_signed_to_ull(req.ts.tv_nsec), &rem.ts,
      96  	       errstr);
      97  
      98  	req.ts.tv_sec = -1;
      99  	req.ts.tv_nsec = -1;
     100  	assert(k_nanosleep(&req.ts, &rem.ts) == -1);
     101  	printf("nanosleep({tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
     102  	       (long long) req.ts.tv_sec,
     103  	       zero_extend_signed_to_ull(req.ts.tv_nsec), &rem.ts,
     104  	       errstr);
     105  
     106  	assert(sigaction(SIGALRM, &act, NULL) == 0);
     107  	assert(sigprocmask(SIG_SETMASK, &set, NULL) == 0);
     108  
     109  	if (setitimer(ITIMER_REAL, &itv, NULL))
     110  		perror_msg_and_skip("setitimer");
     111  
     112  	req.ts.tv_sec = 0;
     113  	req.ts.tv_nsec = 999999999;
     114  	assert(k_nanosleep(&req.ts, &rem.ts) == -1);
     115  	printf("nanosleep({tv_sec=%lld, tv_nsec=%llu}"
     116  	       ", {tv_sec=%lld, tv_nsec=%llu})"
     117  	       " = ? ERESTART_RESTARTBLOCK (Interrupted by signal)\n",
     118  	       (long long) req.ts.tv_sec,
     119  	       zero_extend_signed_to_ull(req.ts.tv_nsec),
     120  	       (long long) rem.ts.tv_sec,
     121  	       zero_extend_signed_to_ull(rem.ts.tv_nsec));
     122  	puts("--- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---");
     123  
     124  	puts("+++ exited with 0 +++");
     125  	return 0;
     126  }
     127  
     128  #else
     129  
     130  SKIP_MAIN_UNDEFINED("__NR_nanosleep")
     131  
     132  #endif