/*
 * Check decoding of ppoll syscall.
 *
 * Copyright (c) 2015-2017 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 <asm/unistd.h>

#ifdef __NR_ppoll

# include <errno.h>
# include <poll.h>
# include <signal.h>
# include <stdio.h>
# include <string.h>
# include <unistd.h>

static const char *errstr;

static long
sys_ppoll(const kernel_ulong_t ufds,
	  const kernel_ulong_t nfds,
	  const kernel_ulong_t tsp,
	  const kernel_ulong_t sigmask,
	  const kernel_ulong_t sigsetsize)
{
	long rc = syscall(__NR_ppoll, ufds, nfds, tsp, sigmask, sigsetsize);
	errstr = sprintrc(rc);
	return rc;
}

int
main(void)
{
	static const kernel_ulong_t bogus_nfds =
		(kernel_ulong_t) 0xdeadbeeffacefeedULL;
	static const kernel_ulong_t bogus_sigsetsize =
		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
	static const char *const POLLWRNORM_str =
		(POLLWRNORM == POLLOUT) ? "" : "|POLLWRNORM";
	static const char *const USR2_CHLD_str =
		(SIGUSR2 < SIGCHLD) ? "USR2 CHLD" : "CHLD USR2";
	void *const efault = tail_alloc(1024) + 1024;
	TAIL_ALLOC_OBJECT_CONST_PTR(struct timespec, ts);
	const unsigned int sigset_size = get_sigset_size();
	void *const sigmask = tail_alloc(sigset_size);
	struct pollfd *fds;
	sigset_t mask;
	int pipe_fd[4];
	long rc;

	sys_ppoll(0, bogus_nfds, 0, 0, bogus_sigsetsize);
	if (ENOSYS == errno)
		perror_msg_and_skip("ppoll");
	printf("ppoll(NULL, %u, NULL, NULL, %llu) = %s\n",
	       (unsigned) bogus_nfds, (unsigned long long) bogus_sigsetsize,
	       errstr);

	sys_ppoll((unsigned long) efault, 42, (unsigned long) efault + 8,
		  (unsigned long) efault + 16, sigset_size);
	printf("ppoll(%p, %u, %p, %p, %u) = %s\n",
	       efault, 42, efault + 8, efault + 16, sigset_size, errstr);

	ts->tv_sec = 0xdeadbeefU;
	ts->tv_nsec = 0xfacefeedU;
	sys_ppoll(0, 0, (unsigned long) ts, 0, sigset_size);
	printf("ppoll(NULL, 0, {tv_sec=%lld, tv_nsec=%llu}, NULL, %u) = %s\n",
	       (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec),
	       sigset_size, errstr);

	ts->tv_sec = (time_t) 0xcafef00ddeadbeefLL;
	ts->tv_nsec = (long) 0xbadc0dedfacefeedL;
	sys_ppoll(0, 0, (unsigned long) ts, 0, sigset_size);
	printf("ppoll(NULL, 0, {tv_sec=%lld, tv_nsec=%llu}, NULL, %u) = %s\n",
	       (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec),
	       sigset_size, errstr);

	if (pipe(pipe_fd) || pipe(pipe_fd + 2))
		perror_msg_and_fail("pipe");

	ts->tv_sec = 42;
	ts->tv_nsec = 999999999;

	const struct pollfd fds1[] = {
		{ .fd = pipe_fd[0], .events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND },
		{ .fd = pipe_fd[1], .events = POLLOUT | POLLWRNORM | POLLWRBAND },
		{ .fd = pipe_fd[2], .events = POLLIN | POLLPRI },
		{ .fd = pipe_fd[3], .events = POLLOUT }
	};
	fds = efault - sizeof(fds1);
	memcpy(fds, fds1, sizeof(fds1));

	sigemptyset(&mask);
	sigaddset(&mask, SIGUSR2);
	sigaddset(&mask, SIGCHLD);
	memcpy(sigmask, &mask, sigset_size);

	rc = sys_ppoll((unsigned long) fds,
		       F8ILL_KULONG_MASK | ARRAY_SIZE(fds1), (unsigned long) ts,
		       (unsigned long) sigmask, sigset_size);
	if (rc != 2)
		perror_msg_and_fail("ppoll 1");
	printf("ppoll([{fd=%d, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}"
	       ", {fd=%d, events=POLLOUT%s|POLLWRBAND}"
#if VERBOSE
	       ", {fd=%d, events=POLLIN|POLLPRI}, {fd=%d, events=POLLOUT}]"
#else
	       ", ...]"
#endif
	       ", %u, {tv_sec=42, tv_nsec=999999999}, [%s], %u) = %ld"
	       " ([{fd=%d, revents=POLLOUT%s}, {fd=%d, revents=POLLOUT}]"
	       ", left {tv_sec=%u, tv_nsec=%u})\n",
	       pipe_fd[0], pipe_fd[1], POLLWRNORM_str,
#if VERBOSE
	       pipe_fd[2], pipe_fd[3],
#endif
	       (unsigned) ARRAY_SIZE(fds1), USR2_CHLD_str,
	       (unsigned) sigset_size, rc, pipe_fd[1], POLLWRNORM_str,
	       pipe_fd[3], (unsigned ) ts->tv_sec, (unsigned) ts->tv_nsec);

	ts->tv_sec = 0;
	ts->tv_nsec = 999;
	const struct pollfd fds2[] = {
		{ .fd = pipe_fd[1], .events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND },
		{ .fd = pipe_fd[0], .events = POLLOUT | POLLWRNORM | POLLWRBAND }
	};
	fds = efault - sizeof(fds2);
	memcpy(fds, fds2, sizeof(fds2));

	memset(&mask, -1, sizeof(mask));
	sigdelset(&mask, SIGHUP);
	sigdelset(&mask, SIGKILL);
	sigdelset(&mask, SIGSTOP);
	memcpy(sigmask, &mask, sigset_size);

	rc = sys_ppoll((unsigned long) fds,
		       F8ILL_KULONG_MASK | ARRAY_SIZE(fds2), (unsigned long) ts,
		       (unsigned long) sigmask, sigset_size);
	if (rc != 0)
		perror_msg_and_fail("ppoll 2");
	printf("ppoll([{fd=%d, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}"
	       ", {fd=%d, events=POLLOUT%s|POLLWRBAND}], %u"
	       ", {tv_sec=0, tv_nsec=999}, ~[HUP KILL STOP], %u)"
	       " = %ld (Timeout)\n",
	       pipe_fd[1], pipe_fd[0], POLLWRNORM_str,
	       (unsigned) ARRAY_SIZE(fds2), sigset_size, rc);

	if (F8ILL_KULONG_SUPPORTED) {
		sys_ppoll(f8ill_ptr_to_kulong(fds), ARRAY_SIZE(fds2),
			  f8ill_ptr_to_kulong(ts), f8ill_ptr_to_kulong(sigmask),
			  sigset_size);
		printf("ppoll(%#llx, %u, %#llx, %#llx, %u) = %s\n",
		       (unsigned long long) f8ill_ptr_to_kulong(fds),
		       (unsigned) ARRAY_SIZE(fds2),
		       (unsigned long long) f8ill_ptr_to_kulong(ts),
		       (unsigned long long) f8ill_ptr_to_kulong(sigmask),
		       (unsigned) sigset_size, errstr);
	}

	puts("+++ exited with 0 +++");
	return 0;
}

#else

SKIP_MAIN_UNDEFINED("__NR_ppoll")

#endif
