(root)/
strace-6.5/
tests-mx32/
sigsuspend.c
       1  /*
       2   * Check decoding of sigsuspend syscall.
       3   *
       4   * Copyright (c) 2017-2018 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2017-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  #ifdef __NR_sigsuspend
      15  
      16  # include <assert.h>
      17  # include <errno.h>
      18  # include <signal.h>
      19  # include <stdio.h>
      20  # include <stdint.h>
      21  # include <string.h>
      22  # include <unistd.h>
      23  
      24  # ifdef MIPS
      25  #  define SIGNAL_MASK_BY_REF 1
      26  # else
      27  #  define SIGNAL_MASK_BY_REF 0
      28  # endif
      29  
      30  static long
      31  k_sigsuspend(const kernel_ulong_t arg1,
      32  	     const kernel_ulong_t arg2,
      33  	     const kernel_ulong_t arg3)
      34  {
      35  	return syscall(__NR_sigsuspend, arg1, arg2, arg3);
      36  }
      37  
      38  static int signo;
      39  static const char *sigtxt[] = {
      40  	[SIGUSR1] = "USR1",
      41  	[SIGUSR2] = "USR2"
      42  };
      43  
      44  static void
      45  handler(int i)
      46  {
      47  	signo = i;
      48  }
      49  
      50  int
      51  main(void)
      52  {
      53  	union {
      54  		sigset_t libc_mask;
      55  		unsigned long old_mask;
      56  	} u;
      57  
      58  	sigemptyset(&u.libc_mask);
      59  	sigaddset(&u.libc_mask, SIGUSR1);
      60  	sigaddset(&u.libc_mask, SIGUSR2);
      61  	if (sigprocmask(SIG_SETMASK, &u.libc_mask, NULL))
      62  		perror_msg_and_fail("sigprocmask");
      63  
      64  	const struct sigaction sa = { .sa_handler = handler };
      65  	if (sigaction(SIGUSR1, &sa, NULL) || sigaction(SIGUSR2, &sa, NULL))
      66  		perror_msg_and_fail("sigaction");
      67  
      68  	raise(SIGUSR1);
      69  	raise(SIGUSR2);
      70  
      71  	u.old_mask = -1UL;
      72  	sigdelset(&u.libc_mask, SIGUSR1);
      73  	const unsigned long mask1 = u.old_mask;
      74  
      75  	u.old_mask = -1UL;
      76  	sigdelset(&u.libc_mask, SIGUSR2);
      77  	const unsigned long mask2 = u.old_mask;
      78  
      79  # if SIGNAL_MASK_BY_REF
      80  	k_sigsuspend((uintptr_t) &mask1, 0xdeadbeef, (uintptr_t) &mask2);
      81  # else
      82  	k_sigsuspend(mask1, 0xdeadbeef, mask2);
      83  # endif
      84  	if (EINTR != errno)
      85  		perror_msg_and_skip("sigsuspend");
      86  
      87  	printf("sigsuspend(~[%s]) = ? ERESTARTNOHAND"
      88  	       " (To be restarted if no handler)\n", sigtxt[signo]);
      89  
      90  	puts("+++ exited with 0 +++");
      91  	return 0;
      92  }
      93  
      94  #else
      95  
      96  SKIP_MAIN_UNDEFINED("__NR_sigsuspend")
      97  
      98  #endif