/*
* Copyright (c) Bull S.A.S. 2008
* 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
*
***************************************************************************
* File: pidns30.c
*
*   Description:
*    This testcase checks if the si_pid is correctly set when a process
*    that has registered for notification on a posix mqueue is in a
*    descendant namespace wrt the process that sends a message to that posix
*    mqueue.
*
*   Test Assertion & Strategy:
*    Parent                                   Child
*    --------------------------------------------------------------------------
*    Create a POSIX mqueue.
*    Create a PID namespace container.
*                                             Open that mqueue for reading
*                                             Register for notification when a
*                                                message arrives in that mqueue
*                                             Install a handler for SIGUSR1.
*    Write something to the mqueue.
*                                             Inside the handler, check that
*                                                si_pid is set to 0
*
*   Usage: <for command-line>
*    pidns30
*
*   History:
*    DATE      NAME                             DESCRIPTION
*    01/12/08  Nadia Derbey               Creation of this test.
*              <Nadia.Derbey@bull.net>
*
******************************************************************************/
#define _GNU_SOURCE 1
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <mqueue.h>
#include "test.h"
#include "linux_syscall_numbers.h"
#include "libclone.h"
#include "pidns_helper.h"

char *TCID = "pidns30";
int TST_TOTAL = 1;

char *mqname = "mq1";
int result = TFAIL;

int errno;
int father_to_child[2];
int child_to_father[2];

#define CHILD_PID       1
#define PARENT_PID      0

#define MSG      "HOW ARE YOU"
#define MSG_PRIO 1

#define NO_STEP	-1
#define F_STEP_0 0x00
#define F_STEP_1 0x01
#define F_STEP_2 0x02
#define F_STEP_3 0x03
#define C_STEP_0 0x10
#define C_STEP_1 0x11
#define C_STEP_2 0x12

mqd_t rc = -1;
mqd_t mqd = -1;

static void remove_pipe(int *fd)
{
	close(fd[0]);
	close(fd[1]);
}

static void remove_mqueue(mqd_t mqd)
{
	mq_close(mqd);
	ltp_syscall(__NR_mq_unlink, mqname);
}

static void cleanup(void)
{
	if (mqd != -1) {
		remove_mqueue(mqd);
	}
	if (rc != -1) {
		remove_mqueue(rc);
	}
	remove_pipe(father_to_child);
	remove_pipe(child_to_father);
}

static void cleanup_child(void)
{
	if (mqd != -1) {
		ltp_syscall(__NR_mq_notify, mqd, NULL);
	}
	cleanup();
}

/*
 * child_signal_handler() - to handle SIGUSR1
 *
 * XXX (garrcoop): add calls to cleanup_child() -- or should this be handled
 * from the libltp signal handler?
 */
static void child_signal_handler(int sig, siginfo_t * si, void *unused)
{
	char buf[256];
	struct mq_attr attr;

	if (si->si_signo != SIGUSR1) {
		printf("received signal = %d unexpectedly\n", si->si_signo);
		return;
	}

	if (si->si_code != SI_MESGQ) {
		printf("expected signal code SI_MESGQ; got %d instead\n",
		       si->si_code);
		return;
	}

	if (si->si_pid) {
		printf("expected signal originator PID = 0; got %d instead\n",
		       si->si_pid);
		return;
	} else {
		printf("signal originator PID = 0\n");
		result = TPASS;
	}

	/*
	 * Now read the message - Be silent on errors since this is not the
	 * test purpose.
	 */
	rc = mq_getattr(si->si_int, &attr);
	if (rc != -1)
		mq_receive(si->si_int, buf, attr.mq_msgsize, NULL);
}

/*
 * child_fn() - Inside container
 *
 * XXX (garrcoop): add more calls to cleanup_child()?
 */
int child_fn(void *arg)
{
	pid_t pid, ppid;
	struct sigaction sa;
	struct sigevent notif;
	char buf[5];

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

	if (pid != CHILD_PID || ppid != PARENT_PID) {
		printf("pidns was not created\n");
		return 1;
	}

	/* Close the appropriate end of each pipe */
	close(child_to_father[0]);
	close(father_to_child[1]);

	while (read(father_to_child[0], buf, 1) != 1)
		sleep(1);

	mqd = ltp_syscall(__NR_mq_open, mqname, O_RDONLY, 0, NULL);
	if (mqd == -1) {
		perror("mq_open failed");
		return 1;
	} else
		printf("mq_open succeeded\n");

	/* Register for notification on message arrival */
	notif.sigev_notify = SIGEV_SIGNAL;
	notif.sigev_signo = SIGUSR1;
	notif.sigev_value.sival_int = mqd;
	if (ltp_syscall(__NR_mq_notify, mqd, &notif) == -1) {
		perror("mq_notify failed");
		return 1;
	} else
		printf("successfully registered for notification\n");

	/* Define handler for SIGUSR1 */
	sa.sa_flags = SA_SIGINFO;
	sigemptyset(&sa.sa_mask);
	sa.sa_sigaction = child_signal_handler;
	if (sigaction(SIGUSR1, &sa, NULL) == -1) {
		perror("sigaction failed");
		return 1;
	} else
		printf("successfully registered handler for SIGUSR1\n");

	/* Ask parent to send a message to the mqueue */
	if (write(child_to_father[1], "c:ok", 5) != 5) {
		perror("write failed");
		return 1;
	}

	sleep(3);

	/* Has parent sent a message? */
	read(father_to_child[0], buf, 5);
	if (strcmp(buf, "f:ok") != 0) {
		printf("parent did not send the message!\n");
		return 1;
	}
	printf("parent is done - cleaning up\n");

	cleanup_child();

	exit(0);
}

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

int main(int argc, char *argv[])
{
	int status;
	char buf[5];
	pid_t cpid;

	setup();

	if (pipe(child_to_father) == -1 || pipe(father_to_child) == -1) {
		tst_brkm(TBROK | TERRNO, cleanup, "pipe failed");
	}

	ltp_syscall(__NR_mq_unlink, mqname);

	/* container creation on PID namespace */
	cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL);
	if (cpid == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "clone failed");

	mqd =
	    ltp_syscall(__NR_mq_open, mqname, O_RDWR | O_CREAT | O_EXCL, 0777,
		    NULL);
	if (mqd == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "mq_open failed");
	else
		tst_resm(TINFO, "successfully created posix mqueue");

	if (write(father_to_child[1], buf, 1) != 1)
		tst_brkm(TBROK | TERRNO, cleanup, "write failed");

	/* Close the appropriate end of each pipe */
	close(child_to_father[1]);
	close(father_to_child[0]);

	/* Is container ready */
	read(child_to_father[0], buf, 5);
	if (strcmp(buf, "c:ok") != 0)
		tst_brkm(TBROK, cleanup,
			 "container did not respond as expected!");

	rc = mq_send(mqd, MSG, strlen(MSG), MSG_PRIO);
	if (rc == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "mq_send failed");
	else
		tst_resm(TINFO, "mq_send succeeded");

	/* Tell the child the message has been sent */
	if (write(father_to_child[1], "f:ok", 5) != 5)
		tst_brkm(TBROK | TERRNO, cleanup, "write failed");

	/* Wait for child to finish */
	if (wait(&status) == -1)
		tst_resm(TBROK | TERRNO, "wait failed");

	cleanup();

	tst_exit();
}
