(root)/
strace-6.5/
tests/
rt_sigsuspend.c
       1  /*
       2   * Check decoding of rt_sigsuspend syscall.
       3   *
       4   * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2021 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  #include <assert.h>
      15  #include <errno.h>
      16  #include <signal.h>
      17  #include <stdio.h>
      18  #include <stdint.h>
      19  #include <string.h>
      20  #include <unistd.h>
      21  
      22  static long
      23  k_sigsuspend(const sigset_t *const set, const unsigned long size)
      24  {
      25  	return syscall(__NR_rt_sigsuspend, set, size);
      26  }
      27  
      28  static void
      29  iterate(const char *const text, const int sig,
      30  	const void *const set, unsigned int size)
      31  {
      32  	for (const void *mask = set;; size >>= 1, mask += size) {
      33  		raise(sig);
      34  		assert(k_sigsuspend(mask, size) == -1);
      35  		if (EINTR == errno) {
      36  			tprintf("rt_sigsuspend(%s, %u) = ? ERESTARTNOHAND"
      37  				" (To be restarted if no handler)\n",
      38  				text, size);
      39  		} else {
      40  			if (size < sizeof(long))
      41  				tprintf("rt_sigsuspend(%p, %u)"
      42  					" = -1 EINVAL (%m)\n",
      43  					mask, size);
      44  			else
      45  				tprintf("rt_sigsuspend(%s, %u)"
      46  					" = -1 EINVAL (%m)\n",
      47  					set == mask ? text : "~[]", size);
      48  		}
      49  		if (!size)
      50  			break;
      51  	}
      52  }
      53  
      54  static void
      55  handler(int signo)
      56  {
      57  }
      58  
      59  int
      60  main(void)
      61  {
      62  	tprintf("%s", "");
      63  
      64  	const unsigned int big_size = 1024 / 8;
      65  	void *k_set = tail_alloc(big_size);
      66  	memset(k_set, 0, big_size);
      67  
      68  	TAIL_ALLOC_OBJECT_CONST_PTR(sigset_t, libc_set);
      69  	sigemptyset(libc_set);
      70  	sigaddset(libc_set, SIGUSR1);
      71  	if (sigprocmask(SIG_SETMASK, libc_set, NULL))
      72  		perror_msg_and_fail("sigprocmask");
      73  
      74  	const struct sigaction sa = {
      75  		.sa_handler = handler
      76  	};
      77  	if (sigaction(SIGUSR1, &sa, NULL))
      78  		perror_msg_and_fail("sigaction");
      79  
      80  	raise(SIGUSR1);
      81  	unsigned int set_size = big_size;
      82  	for (; set_size; set_size >>= 1, k_set += set_size) {
      83  		assert(k_sigsuspend(k_set, set_size) == -1);
      84  		if (EINTR == errno)
      85  			break;
      86  		tprintf("rt_sigsuspend(%p, %u) = -1 EINVAL (%m)\n",
      87  			k_set, set_size);
      88  	}
      89  	if (!set_size)
      90  		perror_msg_and_fail("rt_sigsuspend");
      91  	tprintf("rt_sigsuspend([], %u) = ? ERESTARTNOHAND"
      92  		" (To be restarted if no handler)\n", set_size);
      93  
      94  	sigemptyset(libc_set);
      95  	sigaddset(libc_set, SIGUSR2);
      96  	memcpy(k_set, libc_set, set_size);
      97  	raise(SIGUSR1);
      98  	assert(k_sigsuspend(k_set, set_size) == -1);
      99  	assert(EINTR == errno);
     100  	tprintf("rt_sigsuspend([USR2], %u) = ? ERESTARTNOHAND"
     101  		" (To be restarted if no handler)\n", set_size);
     102  
     103  	sigaddset(libc_set, SIGHUP);
     104  	memcpy(k_set, libc_set, set_size);
     105  	raise(SIGUSR1);
     106  	assert(k_sigsuspend(k_set, set_size) == -1);
     107  	assert(EINTR == errno);
     108  	tprintf("rt_sigsuspend([HUP USR2], %u) = ? ERESTARTNOHAND"
     109  		" (To be restarted if no handler)\n", set_size);
     110  
     111  	sigaddset(libc_set, SIGINT);
     112  	memcpy(k_set, libc_set, set_size);
     113  	raise(SIGUSR1);
     114  	assert(k_sigsuspend(k_set, set_size) == -1);
     115  	assert(EINTR == errno);
     116  	tprintf("rt_sigsuspend([HUP INT USR2], %u) = ? ERESTARTNOHAND"
     117  		" (To be restarted if no handler)\n", set_size);
     118  
     119  	memset(libc_set, -1, sizeof(*libc_set));
     120  	sigdelset(libc_set, SIGUSR1);
     121  	memcpy(k_set, libc_set, set_size);
     122  	raise(SIGUSR1);
     123  	assert(k_sigsuspend(k_set, set_size) == -1);
     124  	assert(EINTR == errno);
     125  	tprintf("rt_sigsuspend(~[USR1], %u) = ? ERESTARTNOHAND"
     126  		" (To be restarted if no handler)\n", set_size);
     127  
     128  	assert(k_sigsuspend(k_set - set_size, set_size << 1) == -1);
     129  	tprintf("rt_sigsuspend(%p, %u) = -1 EINVAL (%m)\n",
     130  		k_set - set_size, set_size << 1);
     131  
     132  	iterate("~[USR1]", SIGUSR1, k_set, set_size >> 1);
     133  
     134  	tprintf("+++ exited with 0 +++\n");
     135  	return 0;
     136  }