/*
 * Check decoding of threads when a non-leader thread invokes execve.
 *
 * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
 * Copyright (c) 2016-2017 The strace developers.
 * 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>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

static pid_t leader;
static pid_t tid;

static void
handler(int signo)
{
}

static unsigned int sigsetsize;
static long
k_sigsuspend(const sigset_t *const set)
{
	return syscall(__NR_rt_sigsuspend, set, sigsetsize);
}

static pid_t
k_gettid(void)
{
	return syscall(__NR_gettid);
}

static void
get_sigsetsize(void)
{
	static const struct sigaction sa = { .sa_handler = handler };
	if (sigaction(SIGUSR1, &sa, NULL))
		perror_msg_and_fail("sigaction");

	sigset_t mask;
	sigemptyset(&mask);
	sigaddset(&mask, SIGUSR1);
	if (sigprocmask(SIG_BLOCK, &mask, NULL))
		perror_msg_and_fail("sigprocmask");

	raise(SIGUSR1);

	sigemptyset(&mask);
	for (sigsetsize = sizeof(mask) / sizeof(long);
	     sigsetsize; sigsetsize >>= 1) {
		long rc = k_sigsuspend(&mask);
		if (!rc)
			error_msg_and_fail("rt_sigsuspend");
		if (EINTR == errno)
			break;
		printf("%-5d rt_sigsuspend(%p, %u) = %s\n",
		       leader, &mask, sigsetsize, sprintrc(rc));
	}
	if (!sigsetsize)
		perror_msg_and_fail("rt_sigsuspend");
	printf("%-5d rt_sigsuspend([], %u) = ? ERESTARTNOHAND"
	       " (To be restarted if no handler)\n", leader, sigsetsize);
}

enum {
	ACTION_exit = 0,
	ACTION_rt_sigsuspend,
	ACTION_nanosleep,
	NUMBER_OF_ACTIONS
};

static const unsigned int NUMBER_OF_ITERATIONS = 1;
static unsigned int action;
static int fds[2];

static unsigned int
arglen(char **args)
{
	char **p;

	for (p = args; *p; ++p)
		;

	return p - args;
}

static void *
thread(void *arg)
{
	tid = k_gettid();

	static char buf[sizeof(action) * 3];
	sprintf(buf, "%u", action + 1);

	char **argv = arg;
	argv[2] = buf;

	if (read(fds[0], fds, sizeof(fds[0])))
		perror_msg_and_fail("execve");

	struct timespec ts = { .tv_nsec = 100000000 };
	(void) clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);

	ts.tv_nsec = 12345;
	printf("%-5d nanosleep({tv_sec=0, tv_nsec=%u}, NULL) = 0\n",
	       tid, (unsigned int) ts.tv_nsec);

	switch (action % NUMBER_OF_ACTIONS) {
		case ACTION_exit:
			printf("%-5d execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
			       ", %p /* %u vars */ <pid changed to %u ...>\n",
			       tid, argv[0], argv[0], argv[1], argv[2],
			       environ, arglen(environ), leader);
			break;
		case ACTION_rt_sigsuspend:
			printf("%-5d execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
			       ", %p /* %u vars */ <unfinished ...>\n"
			       "%-5d <... rt_sigsuspend resumed>) = ?\n",
			       tid, argv[0], argv[0], argv[1], argv[2],
			       environ, arglen(environ),
			       leader);
			break;
		case ACTION_nanosleep:
			printf("%-5d execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
			       ", %p /* %u vars */ <unfinished ...>\n"
			       "%-5d <... nanosleep resumed> <unfinished ...>)"
			       " = ?\n",
			       tid, argv[0], argv[0], argv[1], argv[2],
			       environ, arglen(environ),
			       leader);
			break;
	}

	printf("%-5d +++ superseded by execve in pid %u +++\n"
	       "%-5d <... execve resumed> ) = 0\n",
	       leader, tid,
	       leader);

	(void) nanosleep(&ts, NULL);
	execve(argv[0], argv, environ);
	perror_msg_and_fail("execve");
}

int
main(int ac, char **av)
{
	setvbuf(stdout, NULL, _IONBF, 0);
	leader = getpid();

	if (ac < 3) {
		struct timespec ts = { .tv_nsec = 1 };
		if (clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL))
			perror_msg_and_skip("clock_nanosleep CLOCK_REALTIME");

		get_sigsetsize();
		static char buf[sizeof(sigsetsize) * 3];
		sprintf(buf, "%u", sigsetsize);

		char *argv[] = { av[0], buf, (char *) "0", NULL };
		printf("%-5d execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
		       ", %p /* %u vars */) = 0\n",
		       leader, argv[0], argv[0], argv[1], argv[2],
		       environ, arglen(environ));
		execve(argv[0], argv, environ);
		perror_msg_and_fail("execve");
	}

	sigsetsize = atoi(av[1]);
	action = atoi(av[2]);

	if (action >= NUMBER_OF_ACTIONS * NUMBER_OF_ITERATIONS) {
		printf("%-5d +++ exited with 0 +++\n", leader);
		return 0;
	}

	if (pipe(fds))
		perror_msg_and_fail("pipe");

	pthread_t t;
	errno = pthread_create(&t, NULL, thread, av);
	if (errno)
		perror_msg_and_fail("pthread_create");

	struct timespec ts = { .tv_sec = 123 };
	sigset_t mask;
	sigemptyset(&mask);

	static char leader_str[sizeof(leader) * 3];
	int leader_str_len =
		snprintf(leader_str, sizeof(leader_str), "%-5d", leader);

	switch (action % NUMBER_OF_ACTIONS) {
		case ACTION_exit:
			printf("%s exit(42)%*s= ?\n", leader_str,
			       (int) sizeof(leader_str) - leader_str_len, " ");
			close(fds[1]);
			(void) syscall(__NR_exit, 42);
			break;
		case ACTION_rt_sigsuspend:
			printf("%s rt_sigsuspend([], %u <unfinished ...>\n",
			       leader_str, sigsetsize);
			close(fds[1]);
			(void) k_sigsuspend(&mask);
			break;
		case ACTION_nanosleep:
			printf("%s nanosleep({tv_sec=%u, tv_nsec=0}"
			       ",  <unfinished ...>\n",
			       leader_str, (unsigned int) ts.tv_sec);
			close(fds[1]);
			(void) nanosleep(&ts, 0);
			break;
	}

	return 1;
}
