/*
 *
 *   Copyright (c) Red Hat Inc., 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
 */

/*
 * NAME
 *	signalfd01.c
 *
 * DESCRIPTION
 *	Check signalfd can receive signals
 *
 * USAGE
 * 	signalfd01
 *
 * HISTORY
 *	9/2008 Initial version by Masatake YAMATO <yamato@redhat.com>
 *
 * RESTRICTIONS
 * 	None
 */
#define _GNU_SOURCE

#include "config.h"

#include "test.h"

#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <inttypes.h>
#include "ltp_signal.h"

TCID_DEFINE(signalfd01);
int TST_TOTAL = 1;

#ifndef HAVE_SIGNALFD
#define  USE_STUB
#endif

#if defined HAVE_SYS_SIGNALFD_H
#include <sys/signalfd.h>
#elif defined HAVE_LINUX_SIGNALFD_H
#if defined HAVE_LINUX_TYPES_H
#include <linux/types.h>
#endif
#include <linux/signalfd.h>
#define USE_OWNIMPL
#elif defined HAVE_SIGNALFD_H
#include <signalfd.h>
#else
#define  USE_STUB
#endif

#if defined HAVE_STRUCT_SIGNALFD_SIGINFO_SSI_SIGNO
#define SIGNALFD_PREFIX(FIELD) ssi_##FIELD
#elif defined HAVE_STRUCT_SIGNALFD_SIGINFO_SIGNO
#define SIGNALFD_PREFIX(FIELD) FIELD
#else
#define USE_STUB
#endif

#ifdef USE_STUB
int main(int argc, char **argv)
{
	tst_brkm(TCONF, NULL, "System doesn't support execution of the test");
}

#else
#if defined USE_OWNIMPL
#include "linux_syscall_numbers.h"
int signalfd(int fd, const sigset_t * mask, int flags)
{
	/* Taken from GLIBC. */
	return ltp_syscall(__NR_signalfd, fd, mask, SIGSETSIZE);
}
#endif

void cleanup(void);
void setup(void);

int do_test1(int ntst, int sig)
{
	int sfd_for_next;
	int sfd;
	sigset_t mask;
	pid_t pid;
	struct signalfd_siginfo fdsi;
	ssize_t s;

	sigemptyset(&mask);
	sigaddset(&mask, sig);
	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
		tst_brkm(TBROK, cleanup,
			 "sigprocmask() Failed: errno=%d : %s",
			 errno, strerror(errno));
	}

	TEST(signalfd(-1, &mask, 0));

	if ((sfd = TEST_RETURN) == -1) {
		tst_resm(TFAIL,
			 "signalfd() Failed, errno=%d : %s",
			 TEST_ERRNO, strerror(TEST_ERRNO));
		sfd_for_next = -1;
		return sfd_for_next;

	} else {
		tst_resm(TPASS, "signalfd is created successfully");
		sfd_for_next = sfd;
		goto out;
	}

	if (fcntl(sfd, F_SETFL, O_NONBLOCK) == -1) {
		close(sfd);
		tst_brkm(TBROK, cleanup,
			 "setting signalfd nonblocking mode failed: errno=%d : %s",
			 errno, strerror(errno));
	}

	pid = getpid();
	if (kill(pid, sig) == -1) {
		close(sfd);
		tst_brkm(TBROK, cleanup,
			 "kill(self, %s) failed: errno=%d : %s",
			 strsignal(sig), errno, strerror(errno));
	}

	s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
	if ((s > 0) && (s != sizeof(struct signalfd_siginfo))) {
		tst_resm(TFAIL,
			 "getting incomplete signalfd_siginfo data: "
			 "actual-size=%" PRId32 ", expected-size=%" PRId32,
			 s, sizeof(struct signalfd_siginfo));
		sfd_for_next = -1;
		close(sfd);
		goto out;
	} else if (s < 0) {
		if (errno == EAGAIN) {
			tst_resm(TFAIL,
				 "signalfd_siginfo data is not delivered yet");
			sfd_for_next = -1;
			close(sfd);
			goto out;
		} else {
			close(sfd);
			tst_brkm(TBROK, cleanup,
				 "read signalfd_siginfo data failed: errno=%d : %s",
				 errno, strerror(errno));
		}
	} else if (s == 0) {
		tst_resm(TFAIL, "got EOF unexpectedly");
		sfd_for_next = -1;
		close(sfd);
		goto out;
	}

	if (fdsi.SIGNALFD_PREFIX(signo) == sig) {
		tst_resm(TPASS, "got expected signal");
		sfd_for_next = sfd;
		goto out;
	} else {
		tst_resm(TFAIL, "got unexpected signal: signal=%d : %s",
			 fdsi.SIGNALFD_PREFIX(signo),
			 strsignal(fdsi.SIGNALFD_PREFIX(signo)));
		sfd_for_next = -1;
		close(sfd);
		goto out;
	}

out:
	return sfd_for_next;
}

void do_test2(int ntst, int fd, int sig)
{
	int sfd;
	sigset_t mask;
	pid_t pid;
	struct signalfd_siginfo fdsi;
	ssize_t s;

	sigemptyset(&mask);
	sigaddset(&mask, sig);
	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
		close(fd);
		tst_brkm(TBROK, cleanup,
			 "sigprocmask() Failed: errno=%d : %s",
			 errno, strerror(errno));
	}

	TEST(signalfd(fd, &mask, 0));

	if ((sfd = TEST_RETURN) == -1) {
		tst_resm(TFAIL,
			 "reassignment the file descriptor by signalfd() failed, errno=%d : %s",
			 TEST_ERRNO, strerror(TEST_ERRNO));
		return;
	} else if (sfd != fd) {
		tst_resm(TFAIL,
			 "different fd is returned in reassignment: expected-fd=%d, actual-fd=%d",
			 fd, sfd);
		close(sfd);
		return;

	} else {
		tst_resm(TPASS, "signalfd is successfully reassigned");
		goto out;
	}

	pid = getpid();
	if (kill(pid, sig) == -1) {
		close(sfd);
		tst_brkm(TBROK, cleanup,
			 "kill(self, %s) failed: errno=%d : %s",
			 strsignal(sig), errno, strerror(errno));
	}

	s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
	if ((s > 0) && (s != sizeof(struct signalfd_siginfo))) {
		tst_resm(TFAIL,
			 "getting incomplete signalfd_siginfo data: "
			 "actual-size=%" PRId32 ", expected-size= %" PRId32,
			 s, sizeof(struct signalfd_siginfo));
		goto out;
	} else if (s < 0) {
		if (errno == EAGAIN) {
			tst_resm(TFAIL,
				 "signalfd_siginfo data is not delivered yet");
			goto out;
		} else {
			close(sfd);
			tst_brkm(TBROK, cleanup,
				 "read signalfd_siginfo data failed: errno=%d : %s",
				 errno, strerror(errno));
		}
	} else if (s == 0) {
		tst_resm(TFAIL, "got EOF unexpectedly");
		goto out;
	}

	if (fdsi.SIGNALFD_PREFIX(signo) == sig) {
		tst_resm(TPASS, "got expected signal");
		goto out;
	} else {
		tst_resm(TFAIL, "got unexpected signal: signal=%d : %s",
			 fdsi.SIGNALFD_PREFIX(signo),
			 strsignal(fdsi.SIGNALFD_PREFIX(signo)));
		goto out;
	}

out:
	return;
}

int main(int argc, char **argv)
{
	int lc;
	const char *msg;
	int sfd;

	if ((tst_kvercmp(2, 6, 22)) < 0) {
		tst_resm(TWARN,
			 "This test can only run on kernels that are 2.6.22 and higher");
		exit(0);
	}

	if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
	}

	setup();
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;

		sfd = do_test1(lc, SIGUSR1);
		if (sfd < 0)
			continue;

		do_test2(lc, sfd, SIGUSR2);
		close(sfd);
	}

	cleanup();

	tst_exit();
}

/*
 * setup() - performs all the ONE TIME setup for this test.
 */
void setup(void)
{

	TEST_PAUSE;
}

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

}

#endif
