/*
 * This file is part of rt_sigprocmask strace test.
 *
 * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
 * 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 <sys/syscall.h>

#ifdef __NR_rt_sigprocmask

# include <assert.h>
# include <signal.h>
# include <stdio.h>
# include <string.h>
# include <unistd.h>

static long
k_sigprocmask(const unsigned long how, void *const new_set,
	      void *const old_set, const unsigned long size)
{
	return syscall(__NR_rt_sigprocmask, how, new_set, old_set, size);
}

static void
iterate(const char *const text, void *set, void *old, unsigned int size)
{
	for (;;) {
		if (k_sigprocmask(SIG_UNBLOCK, set, old, size)) {
			if (size < sizeof(long))
				tprintf("rt_sigprocmask(SIG_UNBLOCK"
					", %p, %p, %u) = -1 EINVAL (%m)\n",
					set, old, size);
			else
				tprintf("rt_sigprocmask(SIG_UNBLOCK"
					", %s, %p, %u) = -1 EINVAL (%m)\n",
					text, old, size);
		} else {
			tprintf("rt_sigprocmask(SIG_UNBLOCK, %s, [], %u)"
				" = 0\n", text, size);
		}
		if (!size)
			break;
		size >>= 1;
		set += size;
		old += size;
	}
}

int
main(void)
{
	tprintf("%s", "");

	const unsigned int big_size = 1024 / 8;
	unsigned int set_size;

	for (set_size = big_size; set_size; set_size >>= 1) {
		if (!k_sigprocmask(SIG_SETMASK, NULL, NULL, set_size))
			break;
		tprintf("rt_sigprocmask(SIG_SETMASK, NULL, NULL, %u)"
			" = -1 EINVAL (%m)\n", set_size);
	}
	if (!set_size)
		perror_msg_and_fail("rt_sigprocmask");
	tprintf("rt_sigprocmask(SIG_SETMASK, NULL, NULL, %u) = 0\n",
		set_size);

	void *const k_set = tail_alloc(set_size);
	void *const old_set = tail_alloc(set_size);
	sigset_t *const libc_set = tail_alloc(sizeof(sigset_t));

	memset(k_set, 0, set_size);
	if (k_sigprocmask(SIG_SETMASK, k_set, NULL, set_size))
		perror_msg_and_fail("rt_sigprocmask");
	tprintf("rt_sigprocmask(SIG_SETMASK, [], NULL, %u) = 0\n", set_size);

	if (k_sigprocmask(SIG_UNBLOCK, k_set - set_size, old_set, set_size))
		perror_msg_and_fail("rt_sigprocmask");
	tprintf("rt_sigprocmask(SIG_UNBLOCK, ~[], [], %u) = 0\n", set_size);

	assert(k_sigprocmask(SIG_SETMASK, k_set - set_size,
			     old_set, set_size << 1) == -1);
	tprintf("rt_sigprocmask(SIG_SETMASK, %p, %p, %u) = -1 EINVAL (%m)\n",
		k_set - set_size, old_set, set_size << 1);

	iterate("~[]", k_set - set_size, old_set, set_size >> 1);

	sigemptyset(libc_set);
	sigaddset(libc_set, SIGHUP);
	memcpy(k_set, libc_set, set_size);

	if (k_sigprocmask(SIG_BLOCK, k_set, old_set, set_size))
		perror_msg_and_fail("rt_sigprocmask");
	tprintf("rt_sigprocmask(SIG_BLOCK, [HUP], [], %u) = 0\n", set_size);

	memset(libc_set, -1, sizeof(sigset_t));
	sigdelset(libc_set, SIGHUP);
	memcpy(k_set, libc_set, set_size);

	if (k_sigprocmask(SIG_UNBLOCK, k_set, old_set, set_size))
		perror_msg_and_fail("rt_sigprocmask");
	tprintf("rt_sigprocmask(SIG_UNBLOCK, ~[HUP], [HUP], %u) = 0\n",
		set_size);

	sigdelset(libc_set, SIGKILL);
	memcpy(k_set, libc_set, set_size);

	if (k_sigprocmask(SIG_UNBLOCK, k_set, old_set, set_size))
		perror_msg_and_fail("rt_sigprocmask");
	tprintf("rt_sigprocmask(SIG_UNBLOCK, ~[HUP KILL], [HUP], %u) = 0\n",
		set_size);

	sigemptyset(libc_set);
	sigaddset(libc_set, SIGHUP);
	sigaddset(libc_set, SIGINT);
	sigaddset(libc_set, SIGQUIT);
	sigaddset(libc_set, SIGALRM);
	sigaddset(libc_set, SIGTERM);
	memcpy(k_set, libc_set, set_size);

	if (k_sigprocmask(SIG_BLOCK, k_set, old_set, set_size))
		perror_msg_and_fail("rt_sigprocmask");
	tprintf("rt_sigprocmask(SIG_BLOCK, %s, [HUP], %u) = 0\n",
		"[HUP INT QUIT ALRM TERM]", set_size);

	if (k_sigprocmask(SIG_SETMASK, NULL, old_set, set_size))
		perror_msg_and_fail("rt_sigprocmask");
	tprintf("rt_sigprocmask(SIG_SETMASK, NULL, %s, %u) = 0\n",
		"[HUP INT QUIT ALRM TERM]", set_size);

	assert(k_sigprocmask(SIG_SETMASK, k_set + (set_size >> 1), NULL,
			     set_size) == -1);
	tprintf("rt_sigprocmask(SIG_SETMASK, %p, NULL, %u) = -1 EFAULT (%m)\n",
		k_set + (set_size >> 1), set_size);

	assert(k_sigprocmask(SIG_SETMASK, k_set, old_set + (set_size >> 1),
			     set_size) == -1);
	tprintf("rt_sigprocmask(SIG_SETMASK, %s, %p, %u) = -1 EFAULT (%m)\n",
		"[HUP INT QUIT ALRM TERM]",
		old_set + (set_size >> 1), set_size);

	tprintf("+++ exited with 0 +++\n");
	return 0;
}

#else

SKIP_MAIN_UNDEFINED("__NR_rt_sigprocmask")

#endif
