(root)/
strace-6.5/
tests-mx32/
rt_sigprocmask.c
       1  /*
       2   * Check decoding of rt_sigprocmask 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_sigprocmask(const unsigned long how, void *const new_set,
      22  	      void *const old_set, const unsigned long size)
      23  {
      24  	return syscall(__NR_rt_sigprocmask, how, new_set, old_set, size);
      25  }
      26  
      27  static void
      28  iterate(const char *const text, void *set, void *old, unsigned int size)
      29  {
      30  	for (;;) {
      31  		if (k_sigprocmask(SIG_UNBLOCK, set, old, size)) {
      32  			if (size < sizeof(long))
      33  				tprintf("rt_sigprocmask(SIG_UNBLOCK"
      34  					", %p, %p, %u) = -1 EINVAL (%m)\n",
      35  					set, old, size);
      36  			else
      37  				tprintf("rt_sigprocmask(SIG_UNBLOCK"
      38  					", %s, %p, %u) = -1 EINVAL (%m)\n",
      39  					text, old, size);
      40  		} else {
      41  			tprintf("rt_sigprocmask(SIG_UNBLOCK, %s, [], %u)"
      42  				" = 0\n", text, size);
      43  		}
      44  		if (!size)
      45  			break;
      46  		size >>= 1;
      47  		set += size;
      48  		old += size;
      49  	}
      50  }
      51  
      52  int
      53  main(void)
      54  {
      55  	tprintf("%s", "");
      56  
      57  	const unsigned int big_size = 1024 / 8;
      58  	unsigned int set_size;
      59  
      60  	for (set_size = big_size; set_size; set_size >>= 1) {
      61  		if (!k_sigprocmask(SIG_SETMASK, NULL, NULL, set_size))
      62  			break;
      63  		tprintf("rt_sigprocmask(SIG_SETMASK, NULL, NULL, %u)"
      64  			" = -1 EINVAL (%m)\n", set_size);
      65  	}
      66  	if (!set_size)
      67  		perror_msg_and_fail("rt_sigprocmask");
      68  	tprintf("rt_sigprocmask(SIG_SETMASK, NULL, NULL, %u) = 0\n",
      69  		set_size);
      70  
      71  	void *const k_set = tail_alloc(set_size);
      72  	void *const old_set = tail_alloc(set_size);
      73  	TAIL_ALLOC_OBJECT_CONST_PTR(sigset_t, libc_set);
      74  
      75  	memset(k_set, 0, set_size);
      76  	if (k_sigprocmask(SIG_SETMASK, k_set, NULL, set_size))
      77  		perror_msg_and_fail("rt_sigprocmask");
      78  	tprintf("rt_sigprocmask(SIG_SETMASK, [], NULL, %u) = 0\n", set_size);
      79  
      80  	if (k_sigprocmask(SIG_UNBLOCK, k_set - set_size, old_set, set_size))
      81  		perror_msg_and_fail("rt_sigprocmask");
      82  	tprintf("rt_sigprocmask(SIG_UNBLOCK, ~[], [], %u) = 0\n", set_size);
      83  
      84  	assert(k_sigprocmask(SIG_SETMASK, k_set - set_size,
      85  			     old_set, set_size << 1) == -1);
      86  	tprintf("rt_sigprocmask(SIG_SETMASK, %p, %p, %u) = -1 EINVAL (%m)\n",
      87  		k_set - set_size, old_set, set_size << 1);
      88  
      89  	iterate("~[]", k_set - set_size, old_set, set_size >> 1);
      90  
      91  	sigemptyset(libc_set);
      92  	sigaddset(libc_set, SIGHUP);
      93  	memcpy(k_set, libc_set, set_size);
      94  
      95  	if (k_sigprocmask(SIG_BLOCK, k_set, old_set, set_size))
      96  		perror_msg_and_fail("rt_sigprocmask");
      97  	tprintf("rt_sigprocmask(SIG_BLOCK, [HUP], [], %u) = 0\n", set_size);
      98  
      99  	memset(libc_set, -1, sizeof(sigset_t));
     100  	sigdelset(libc_set, SIGHUP);
     101  	memcpy(k_set, libc_set, set_size);
     102  
     103  	if (k_sigprocmask(SIG_UNBLOCK, k_set, old_set, set_size))
     104  		perror_msg_and_fail("rt_sigprocmask");
     105  	tprintf("rt_sigprocmask(SIG_UNBLOCK, ~[HUP], [HUP], %u) = 0\n",
     106  		set_size);
     107  
     108  	sigdelset(libc_set, SIGKILL);
     109  	memcpy(k_set, libc_set, set_size);
     110  
     111  	if (k_sigprocmask(SIG_UNBLOCK, k_set, old_set, set_size))
     112  		perror_msg_and_fail("rt_sigprocmask");
     113  	tprintf("rt_sigprocmask(SIG_UNBLOCK, ~[HUP KILL], [HUP], %u) = 0\n",
     114  		set_size);
     115  
     116  	sigemptyset(libc_set);
     117  	sigaddset(libc_set, SIGHUP);
     118  	sigaddset(libc_set, SIGINT);
     119  	sigaddset(libc_set, SIGQUIT);
     120  	sigaddset(libc_set, SIGALRM);
     121  	sigaddset(libc_set, SIGTERM);
     122  	memcpy(k_set, libc_set, set_size);
     123  
     124  	if (k_sigprocmask(SIG_BLOCK, k_set, old_set, set_size))
     125  		perror_msg_and_fail("rt_sigprocmask");
     126  	tprintf("rt_sigprocmask(SIG_BLOCK, %s, [HUP], %u) = 0\n",
     127  		"[HUP INT QUIT ALRM TERM]", set_size);
     128  
     129  	if (k_sigprocmask(SIG_SETMASK, NULL, old_set, set_size))
     130  		perror_msg_and_fail("rt_sigprocmask");
     131  	tprintf("rt_sigprocmask(SIG_SETMASK, NULL, %s, %u) = 0\n",
     132  		"[HUP INT QUIT ALRM TERM]", set_size);
     133  
     134  	assert(k_sigprocmask(SIG_SETMASK, k_set + (set_size >> 1), NULL,
     135  			     set_size) == -1);
     136  	tprintf("rt_sigprocmask(SIG_SETMASK, %p, NULL, %u) = -1 EFAULT (%m)\n",
     137  		k_set + (set_size >> 1), set_size);
     138  
     139  	assert(k_sigprocmask(SIG_SETMASK, k_set, old_set + (set_size >> 1),
     140  			     set_size) == -1);
     141  	tprintf("rt_sigprocmask(SIG_SETMASK, %s, %p, %u) = -1 EFAULT (%m)\n",
     142  		"[HUP INT QUIT ALRM TERM]",
     143  		old_set + (set_size >> 1), set_size);
     144  
     145  	tprintf("+++ exited with 0 +++\n");
     146  	return 0;
     147  }