/*
 * Copyright (c) 2014 Fujitsu Ltd.
 * Author: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/*
 * Description:
 *     Basic test for msgrcv(2) using MSG_EXCEPT, MSG_NOERROR
 */

#define  _GNU_SOURCE
#include <sys/wait.h>
#include "test.h"
#include "ipcmsg.h"


#define MSGTYPE1	1
#define MSGTYPE2	2
#define MSG1	"message type1"
#define MSG2	"message type2"

static void wait4child(pid_t child, char *tst_flag);

static void test_msg_except(void);
static void test_msg_noerror(void);

static void (*testfunc[])(void) = { test_msg_except, test_msg_noerror };

char *TCID = "msgrcv07";
int TST_TOTAL = ARRAY_SIZE(testfunc);

int main(int ac, char **av)
{
	int lc;
	const char *msg;
	int i;

	msg = parse_opts(ac, av, NULL, NULL);
	if (msg != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

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

		for (i = 0; i < TST_TOTAL; i++)
			(*testfunc[i])();
	}

	cleanup();
	tst_exit();
}

void setup(void)
{
	tst_sig(FORK, DEF_HANDLER, cleanup);

	TEST_PAUSE;
}

static void test_msg_except(void)
{
	pid_t child_pid;
	int msgq_id;
	MSGBUF snd_buf1 = {.mtype = MSGTYPE1, .mtext = MSG1};
	MSGBUF snd_buf2 = {.mtype = MSGTYPE2, .mtext = MSG2};
	MSGBUF rcv_buf;

	msgq_id = msgget(IPC_PRIVATE, MSG_RW);
	if (msgq_id == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "Can't create message queue");

	if (msgsnd(msgq_id, &snd_buf1, MSGSIZE, 0) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message");

	if (msgsnd(msgq_id, &snd_buf2, MSGSIZE, 0) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message");

	child_pid = tst_fork();
	if (child_pid == -1) {
		tst_brkm(TBROK, cleanup, "fork failed");
	} else if (child_pid > 0) {
		wait4child(child_pid, "MSG_EXCEPT");
	} else {
		memset(&rcv_buf, 0, sizeof(rcv_buf));
		TEST(msgrcv(msgq_id, &rcv_buf, MSGSIZE, MSGTYPE2, MSG_EXCEPT));
		if (TEST_RETURN == -1) {
			fprintf(stderr, "msgrcv(MSG_EXCEPT) failed\n");
			exit(TBROK);
		}
		/* check the received message */
		if (strcmp(rcv_buf.mtext, MSG1) == 0 &&
		    rcv_buf.mtype == MSGTYPE1)
			exit(TPASS);
		else
			exit(TFAIL);
	}

	rm_queue(msgq_id);
}


static void test_msg_noerror(void)
{
	pid_t child_pid;
	int msg_len, msgq_id;
	MSGBUF snd_buf1 = {.mtype = MSGTYPE1, .mtext = MSG1};
	MSGBUF rcv_buf;

	msgq_id = msgget(IPC_PRIVATE, MSG_RW);
	if (msgq_id == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "Can't create message queue");

	if (msgsnd(msgq_id, &snd_buf1, MSGSIZE, 0) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message");

	child_pid = tst_fork();
	if (child_pid == -1) {
		tst_brkm(TBROK, cleanup, "fork failed");
	} else if (child_pid > 0) {
		wait4child(child_pid, "MSG_NOERROR");
	} else {
		msg_len = sizeof(MSG1) / 2;
		memset(&rcv_buf, 0, sizeof(rcv_buf));

		TEST(msgrcv(msgq_id, &rcv_buf, msg_len, MSGTYPE1, MSG_NOERROR));
		if (TEST_RETURN == -1)
			exit(TFAIL);

		if (strncmp(rcv_buf.mtext, MSG1, msg_len) == 0 &&
		    rcv_buf.mtype == MSGTYPE1)
			exit(TPASS);
		exit(TFAIL);
	}

	rm_queue(msgq_id);
}

static void wait4child(pid_t child, char *tst_flag)
{
	int status;
	int ret;

	if (waitpid(child, &status, 0) == -1)
		tst_resm(TBROK | TERRNO, "waitpid");
	if (WIFEXITED(status)) {
		ret = WEXITSTATUS(status);
		if (ret == 0)
			tst_resm(TPASS, "test %s success", tst_flag);
		else if (ret == 1)
			tst_resm(TFAIL, "test %s failed", tst_flag);
		else
			tst_brkm(TBROK, cleanup, "msgrcv failed unexpectedly");
	} else {
		tst_brkm(TBROK, cleanup, "child process terminated "
			 "abnormally. status: %d", status);
	}
}

void cleanup(void)
{
}
