/*
* Copyright (c) International Business Machines Corp., 2007
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
***************************************************************************

* * Test Assertion.
* *----------------
* * kill -USR1 container_init
* *	- from the parent process and also inside a container
* *	- Where init has defined a custom handler for USR1
* *	- Should call the handler and
* *	- Verify whether the signal handler is called from the proper process.
* *
* * Description:
* *  Create PID namespace container.
* *  Container init defines the handler for SIGUSR1 and waits indefinetly.
* *  Parent sends SIGUSR1 to container init.
* *  The signal handler is handled and the cont-init resumes normally.
* *  From the container, again the signal SIGUSR1 is sent.
* *  In the sig-handler check if it's invoked from correct pid(parent/container)
* *  If cont-init wakes up properly -
* *  it will return expected value at exit which is verified at the end.
* *
* * History:
* *  DATE	  NAME				   DESCRIPTION
* *  04/11/08  Veerendra C  <vechandr@in.ibm.com> Verifying cont init kill -USR1
*
*******************************************************************************/
#include "config.h"

#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include "test.h"
#include <libclone.h>
#include "pidns_helper.h"

#define CHILD_PID	1
#define PARENT_PID	0

char *TCID = "pidns16";
int TST_TOTAL = 3;

/*
 * cleanup() - performs all ONE TIME cleanup for this test at
 *			 completion or premature exit.
 */
void cleanup()
{

}

void child_signal_handler(int sig, siginfo_t * si, void *unused)
{
	static int c = 1;
	pid_t expected_pid;

	/* Verifying from which process the signal handler is signalled */

	switch (c) {
	case 1:
		expected_pid = PARENT_PID;
		break;
	case 2:
		expected_pid = CHILD_PID;
		break;
	default:
		tst_resm(TBROK, "child should NOT be signalled 3+ times");
		return;
	}

	if (si->si_pid == expected_pid)
		tst_resm(TPASS, "child is signalled from expected pid %d",
			 expected_pid);
	else
		tst_resm(TFAIL, "child is signalled from unexpected pid %d,"
			 " expecting pid %d", si->si_pid, expected_pid);

	c++;
}

/*
 * child_fn() - Inside container
 */
int child_fn(void *ttype)
{
	struct sigaction sa;
	pid_t pid, ppid;

	/* Set process id and parent pid */
	pid = getpid();
	ppid = getppid();

	if ((pid != CHILD_PID) || (ppid != PARENT_PID))
		tst_resm(TBROK, "pidns is not created.");

	/* Set signal handler for SIGUSR1, also mask other signals */
	sa.sa_flags = SA_SIGINFO;
	sigemptyset(&sa.sa_mask);
	sa.sa_sigaction = child_signal_handler;
	if (sigaction(SIGUSR1, &sa, NULL) == -1)
		tst_resm(TBROK, "%d: sigaction() failed", pid);

	pause();
	tst_resm(TINFO, "Container: Resumed after receiving SIGUSR1 "
		 "from parentNS ");
	if (kill(pid, SIGUSR1) != 0) {
		tst_resm(TFAIL, "kill(SIGUSR1) fails.");
		cleanup();
	}
	tst_resm(TINFO, "Container: Resumed after sending SIGUSR1 "
		 "from container itself");
	_exit(10);
}

static void setup(void)
{
	tst_require_root(NULL);
	check_newpid();
}

/***********************************************************************
*   M A I N
***********************************************************************/
int main(int argc, char *argv[])
{
	int status;
	pid_t cpid;

	setup();

	cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL);

	if (cpid < 0) {
		tst_resm(TBROK, "clone() failed.");
		cleanup();
	}

	sleep(1);
	if (kill(cpid, SIGUSR1) != 0) {
		tst_resm(TFAIL, "kill(SIGUSR1) fails.");
		cleanup();
	}
	sleep(1);
	if (waitpid(cpid, &status, 0) < 0)
		tst_resm(TWARN, "waitpid() failed.");

	if ((WIFEXITED(status)) && (WEXITSTATUS(status) == 10))
		tst_resm(TPASS, "container init continued successfuly, "
			 "after handling signal -USR1");
	else
		tst_resm(TFAIL, "c-init failed to continue after "
			 "passing kill -USR1");
	cleanup();
	tst_exit();
}
