(root)/
strace-6.5/
tests/
rt_sigpending.c
       1  /*
       2   * Check decoding of rt_sigpending 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 <signal.h>
      16  #include <stdio.h>
      17  #include <string.h>
      18  #include <unistd.h>
      19  
      20  static long
      21  k_sigpending(void *const set, const unsigned long size)
      22  {
      23  	return syscall(__NR_rt_sigpending, set, size);
      24  }
      25  
      26  static void
      27  iterate(const char *const text, unsigned int size, void *set)
      28  {
      29  	for (;;) {
      30  		if (k_sigpending(set, size)) {
      31  			tprintf("rt_sigpending(%p, %u) = -1 EFAULT (%m)\n",
      32  				set, size);
      33  			break;
      34  		}
      35  		if (size) {
      36  #ifdef WORDS_BIGENDIAN
      37  			if (size < sizeof(long))
      38  				tprintf("rt_sigpending(%s, %u) = 0\n",
      39  					"[]", size);
      40  			else
      41  #endif
      42  				tprintf("rt_sigpending(%s, %u) = 0\n",
      43  					text, size);
      44  		} else {
      45  			tprintf("rt_sigpending(%p, %u) = 0\n", set, size);
      46  			break;
      47  		}
      48  		size >>= 1;
      49  		set += size;
      50  	}
      51  }
      52  
      53  int
      54  main(void)
      55  {
      56  	tprintf("%s", "");
      57  
      58  	const unsigned int big_size = 1024 / 8;
      59  	void *k_set = tail_alloc(big_size);
      60  	TAIL_ALLOC_OBJECT_CONST_PTR(sigset_t, libc_set);
      61  
      62  	sigemptyset(libc_set);
      63  	if (sigprocmask(SIG_SETMASK, libc_set, NULL))
      64  		perror_msg_and_fail("sigprocmask");
      65  
      66  	memset(k_set, 0, big_size);
      67  	unsigned int set_size = big_size;
      68  	for (; set_size; set_size >>= 1, k_set += set_size) {
      69  		if (!k_sigpending(k_set, set_size))
      70  			break;
      71  		tprintf("rt_sigpending(%p, %u) = -1 EINVAL (%m)\n",
      72  			k_set, set_size);
      73  	}
      74  	if (!set_size)
      75  		perror_msg_and_fail("rt_sigpending");
      76  	tprintf("rt_sigpending(%s, %u) = 0\n", "[]", set_size);
      77  
      78  	iterate("[]", set_size >> 1, k_set + (set_size >> 1));
      79  
      80  	void *const efault = k_set + (set_size >> 1);
      81  	assert(k_sigpending(efault, set_size) == -1);
      82  	tprintf("rt_sigpending(%p, %u) = -1 EFAULT (%m)\n",
      83  		efault, set_size);
      84  
      85  	sigaddset(libc_set, SIGHUP);
      86  	if (sigprocmask(SIG_SETMASK, libc_set, NULL))
      87  		perror_msg_and_fail("sigprocmask");
      88  	raise(SIGHUP);
      89  
      90  	iterate("[HUP]", set_size, k_set);
      91  
      92  	sigaddset(libc_set, SIGINT);
      93  	if (sigprocmask(SIG_SETMASK, libc_set, NULL))
      94  		perror_msg_and_fail("sigprocmask");
      95  	raise(SIGINT);
      96  
      97  	iterate("[HUP INT]", set_size, k_set);
      98  
      99  	tprintf("+++ exited with 0 +++\n");
     100  	return 0;
     101  }