From: Dmitry V. Levin Date: Fri, 19 Feb 2016 16:07:43 +0000 (+0000) Subject: tests: add rt_sigsuspend.test X-Git-Tag: v4.12~528 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9649ac1c8b5d217b82c818187bb476d8da2838f4;p=strace tests: add rt_sigsuspend.test * tests/rt_sigsuspend.c: New file. * tests/rt_sigsuspend.test: New test. * tests/.gitignore: Add rt_sigsuspend. * tests/Makefile.am (check_PROGRAMS): Likewise. (TESTS): Add rt_sigsuspend.test. --- diff --git a/tests/.gitignore b/tests/.gitignore index 0b3edf40..bdce2dbb 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -85,6 +85,7 @@ restart_syscall rt_sigpending rt_sigprocmask rt_sigqueueinfo +rt_sigsuspend rt_sigtimedwait rt_tgsigqueueinfo sched_xetaffinity diff --git a/tests/Makefile.am b/tests/Makefile.am index ecf4b8a4..54f3d5b9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -133,6 +133,7 @@ check_PROGRAMS = \ rt_sigpending \ rt_sigprocmask \ rt_sigqueueinfo \ + rt_sigsuspend \ rt_sigtimedwait \ rt_tgsigqueueinfo \ sched_xetaffinity \ @@ -288,6 +289,7 @@ TESTS = \ rt_sigpending.test \ rt_sigprocmask.test \ rt_sigqueueinfo.test \ + rt_sigsuspend.test \ rt_sigtimedwait.test \ rt_tgsigqueueinfo.test \ sched_xetaffinity.test \ diff --git a/tests/rt_sigsuspend.c b/tests/rt_sigsuspend.c new file mode 100644 index 00000000..07a50e08 --- /dev/null +++ b/tests/rt_sigsuspend.c @@ -0,0 +1,165 @@ +/* + * This file is part of rt_sigsuspend strace test. + * + * Copyright (c) 2016 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" +#include + +#ifdef __NR_rt_sigsuspend + +# include +# include +# include +# include +# include +# include +# include + +static long +k_sigsuspend(const sigset_t *const set, const unsigned long size) +{ + return syscall(__NR_rt_sigsuspend, set, size); +} + +static void +iterate(const char *const text, const int sig, + const void *set, unsigned int size) +{ + for (;;) { + raise(sig); + assert(k_sigsuspend(set, size) == -1); + if (EINTR == errno) { + tprintf("rt_sigsuspend(%s, %u) = ? ERESTARTNOHAND" + " (To be restarted if no handler)\n", + text, size); + } else { + if (size < sizeof(long)) + tprintf("rt_sigsuspend(%p, %u)" + " = -1 EINVAL (%m)\n", + set, size); + else + tprintf("rt_sigsuspend(%s, %u)" + " = -1 EINVAL (%m)\n", + text, size); + } + if (!size) + break; + size >>= 1; + set += size; + } +} + +static void +handler(int signo) +{ +} + +int +main(void) +{ + tprintf("%s", ""); + + const unsigned int big_size = 1024 / 8; + void *k_set = tail_alloc(big_size); + memset(k_set, 0, big_size); + + sigset_t *const libc_set = tail_alloc(sizeof(sigset_t)); + sigemptyset(libc_set); + sigaddset(libc_set, SIGUSR1); + if (sigprocmask(SIG_SETMASK, libc_set, NULL)) + perror_msg_and_fail("sigprocmask"); + + const struct sigaction sa = { + .sa_handler = handler + }; + if (sigaction(SIGUSR1, &sa, NULL)) + perror_msg_and_fail("sigaction"); + + raise(SIGUSR1); + unsigned int set_size = big_size; + for (; set_size; set_size >>= 1, k_set += set_size) { + assert(k_sigsuspend(k_set, set_size) == -1); + if (EINTR == errno) + break; + tprintf("rt_sigsuspend(%p, %u) = -1 EINVAL (%m)\n", + k_set, set_size); + } + if (!set_size) + perror_msg_and_fail("rt_sigsuspend"); + tprintf("rt_sigsuspend([], %u) = ? ERESTARTNOHAND" + " (To be restarted if no handler)\n", set_size); + + sigemptyset(libc_set); + sigaddset(libc_set, SIGUSR2); + memcpy(k_set, libc_set, set_size); + raise(SIGUSR1); + assert(k_sigsuspend(k_set, set_size) == -1); + assert(EINTR == errno); + tprintf("rt_sigsuspend([USR2], %u) = ? ERESTARTNOHAND" + " (To be restarted if no handler)\n", set_size); + + sigaddset(libc_set, SIGHUP); + memcpy(k_set, libc_set, set_size); + raise(SIGUSR1); + assert(k_sigsuspend(k_set, set_size) == -1); + assert(EINTR == errno); + tprintf("rt_sigsuspend([HUP USR2], %u) = ? ERESTARTNOHAND" + " (To be restarted if no handler)\n", set_size); + + sigaddset(libc_set, SIGINT); + memcpy(k_set, libc_set, set_size); + raise(SIGUSR1); + assert(k_sigsuspend(k_set, set_size) == -1); + assert(EINTR == errno); + tprintf("rt_sigsuspend([HUP INT USR2], %u) = ? ERESTARTNOHAND" + " (To be restarted if no handler)\n", set_size); + + memset(libc_set, -1, sizeof(*libc_set)); + sigdelset(libc_set, SIGUSR1); + memcpy(k_set, libc_set, set_size); + raise(SIGUSR1); + assert(k_sigsuspend(k_set, set_size) == -1); + assert(EINTR == errno); + tprintf("rt_sigsuspend(~[USR1], %u) = ? ERESTARTNOHAND" + " (To be restarted if no handler)\n", set_size); + + assert(k_sigsuspend(k_set - set_size, set_size << 1) == -1); + tprintf("rt_sigsuspend(%p, %u) = -1 EINVAL (%m)\n", + k_set - set_size, set_size << 1); + + iterate("~[USR1]", SIGUSR1, k_set, set_size >> 1); + + tprintf("+++ exited with 0 +++\n"); + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_rt_sigsuspend") + +#endif diff --git a/tests/rt_sigsuspend.test b/tests/rt_sigsuspend.test new file mode 100755 index 00000000..ef6636e3 --- /dev/null +++ b/tests/rt_sigsuspend.test @@ -0,0 +1,11 @@ +#!/bin/sh + +# Check rt_sigsuspend syscall decoding. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +OUT="$LOG.out" +run_strace -a20 -ert_sigsuspend -esignal=none $args > "$OUT" +match_diff "$LOG" "$OUT" +rm -f "$OUT"