19649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin/* 29649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * This file is part of rt_sigsuspend strace test. 39649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * 49649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org> 59649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * All rights reserved. 69649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * 79649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * Redistribution and use in source and binary forms, with or without 89649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * modification, are permitted provided that the following conditions 99649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * are met: 109649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * 1. Redistributions of source code must retain the above copyright 119649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * notice, this list of conditions and the following disclaimer. 129649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * 2. Redistributions in binary form must reproduce the above copyright 139649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * notice, this list of conditions and the following disclaimer in the 149649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * documentation and/or other materials provided with the distribution. 159649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * 3. The name of the author may not be used to endorse or promote products 169649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * derived from this software without specific prior written permission. 179649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * 189649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 199649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 209649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 219649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 229649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 239649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 249649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 259649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 269649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 279649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 289649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin */ 299649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 309649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin#include "tests.h" 316a2f43ce6469c06d0244a07cea3d04f3740a66ceDmitry V. Levin#include <asm/unistd.h> 329649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 339649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin#ifdef __NR_rt_sigsuspend 349649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 359649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin# include <assert.h> 369649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin# include <errno.h> 379649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin# include <signal.h> 389649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin# include <stdio.h> 399649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin# include <stdint.h> 409649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin# include <string.h> 419649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin# include <unistd.h> 429649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 439649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levinstatic long 449649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levink_sigsuspend(const sigset_t *const set, const unsigned long size) 459649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin{ 469649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin return syscall(__NR_rt_sigsuspend, set, size); 479649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin} 489649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 499649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levinstatic void 509649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Leviniterate(const char *const text, const int sig, 51c8cc0f2a87b5f7a33bf7dee39ba4ba2dc5cb4cb4Dmitry V. Levin const void *const set, unsigned int size) 529649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin{ 53c8cc0f2a87b5f7a33bf7dee39ba4ba2dc5cb4cb4Dmitry V. Levin const void *mask; 54c8cc0f2a87b5f7a33bf7dee39ba4ba2dc5cb4cb4Dmitry V. Levin 55c8cc0f2a87b5f7a33bf7dee39ba4ba2dc5cb4cb4Dmitry V. Levin for (mask = set;; size >>= 1, mask += size) { 569649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin raise(sig); 57c8cc0f2a87b5f7a33bf7dee39ba4ba2dc5cb4cb4Dmitry V. Levin assert(k_sigsuspend(mask, size) == -1); 589649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin if (EINTR == errno) { 599649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend(%s, %u) = ? ERESTARTNOHAND" 609649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin " (To be restarted if no handler)\n", 619649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin text, size); 629649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin } else { 639649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin if (size < sizeof(long)) 649649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend(%p, %u)" 659649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin " = -1 EINVAL (%m)\n", 66c8cc0f2a87b5f7a33bf7dee39ba4ba2dc5cb4cb4Dmitry V. Levin mask, size); 679649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin else 689649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend(%s, %u)" 699649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin " = -1 EINVAL (%m)\n", 70c8cc0f2a87b5f7a33bf7dee39ba4ba2dc5cb4cb4Dmitry V. Levin set == mask ? text : "~[]", size); 719649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin } 729649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin if (!size) 739649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin break; 749649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin } 759649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin} 769649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 779649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levinstatic void 789649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levinhandler(int signo) 799649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin{ 809649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin} 819649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 829649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levinint 839649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levinmain(void) 849649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin{ 859649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("%s", ""); 869649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 879649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin const unsigned int big_size = 1024 / 8; 889649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin void *k_set = tail_alloc(big_size); 899649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin memset(k_set, 0, big_size); 909649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 919649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin sigset_t *const libc_set = tail_alloc(sizeof(sigset_t)); 929649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin sigemptyset(libc_set); 939649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin sigaddset(libc_set, SIGUSR1); 949649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin if (sigprocmask(SIG_SETMASK, libc_set, NULL)) 959649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin perror_msg_and_fail("sigprocmask"); 969649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 979649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin const struct sigaction sa = { 989649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin .sa_handler = handler 999649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin }; 1009649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin if (sigaction(SIGUSR1, &sa, NULL)) 1019649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin perror_msg_and_fail("sigaction"); 1029649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1039649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin raise(SIGUSR1); 1049649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin unsigned int set_size = big_size; 1059649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin for (; set_size; set_size >>= 1, k_set += set_size) { 1069649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(k_sigsuspend(k_set, set_size) == -1); 1079649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin if (EINTR == errno) 1089649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin break; 1099649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend(%p, %u) = -1 EINVAL (%m)\n", 1109649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin k_set, set_size); 1119649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin } 1129649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin if (!set_size) 1139649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin perror_msg_and_fail("rt_sigsuspend"); 1149649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend([], %u) = ? ERESTARTNOHAND" 1159649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin " (To be restarted if no handler)\n", set_size); 1169649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1179649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin sigemptyset(libc_set); 1189649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin sigaddset(libc_set, SIGUSR2); 1199649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin memcpy(k_set, libc_set, set_size); 1209649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin raise(SIGUSR1); 1219649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(k_sigsuspend(k_set, set_size) == -1); 1229649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(EINTR == errno); 1239649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend([USR2], %u) = ? ERESTARTNOHAND" 1249649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin " (To be restarted if no handler)\n", set_size); 1259649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1269649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin sigaddset(libc_set, SIGHUP); 1279649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin memcpy(k_set, libc_set, set_size); 1289649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin raise(SIGUSR1); 1299649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(k_sigsuspend(k_set, set_size) == -1); 1309649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(EINTR == errno); 1319649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend([HUP USR2], %u) = ? ERESTARTNOHAND" 1329649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin " (To be restarted if no handler)\n", set_size); 1339649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1349649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin sigaddset(libc_set, SIGINT); 1359649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin memcpy(k_set, libc_set, set_size); 1369649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin raise(SIGUSR1); 1379649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(k_sigsuspend(k_set, set_size) == -1); 1389649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(EINTR == errno); 1399649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend([HUP INT USR2], %u) = ? ERESTARTNOHAND" 1409649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin " (To be restarted if no handler)\n", set_size); 1419649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1429649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin memset(libc_set, -1, sizeof(*libc_set)); 1439649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin sigdelset(libc_set, SIGUSR1); 1449649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin memcpy(k_set, libc_set, set_size); 1459649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin raise(SIGUSR1); 1469649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(k_sigsuspend(k_set, set_size) == -1); 1479649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(EINTR == errno); 1489649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend(~[USR1], %u) = ? ERESTARTNOHAND" 1499649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin " (To be restarted if no handler)\n", set_size); 1509649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1519649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin assert(k_sigsuspend(k_set - set_size, set_size << 1) == -1); 1529649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("rt_sigsuspend(%p, %u) = -1 EINVAL (%m)\n", 1539649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin k_set - set_size, set_size << 1); 1549649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1559649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin iterate("~[USR1]", SIGUSR1, k_set, set_size >> 1); 1569649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1579649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin tprintf("+++ exited with 0 +++\n"); 1589649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin return 0; 1599649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin} 1609649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1619649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin#else 1629649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1639649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. LevinSKIP_MAIN_UNDEFINED("__NR_rt_sigsuspend") 1649649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin 1659649ac1c8b5d217b82c818187bb476d8da2838f4Dmitry V. Levin#endif 166