/*
 * Copyright (c) International Business Machines  Corp., 2001
 * 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:
 * Verify that,
 *  1. msync() fails with -1 return value and sets errno to EBUSY
 *     if MS_INVALIDATE was specified in flags, and a memory lock
 *     exists for the specified address range.
 *  2. msync() fails with -1 return value and sets errno to EINVAL
 *     if addr is not a multiple of PAGESIZE; or any bit other than
 *     MS_ASYNC | MS_INVALIDATE | MS_SYNC is set in flags; or both
 *     MS_SYNC and MS_ASYNC are set in flags.
 *  3. msync() fails with -1 return value and sets errno to ENOMEM
 *     if the indicated memory (or part of it) was not mapped.
 */

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <pwd.h>
#include <sys/resource.h>

#include "test.h"
#include "safe_macros.h"

#define INV_SYNC	-1
#define TEMPFILE	"msync_file"
#define BUF_SIZE	256

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

static int fd;
static char *addr1;
static char *addr2;
static char *addr3;

#if !defined(UCLINUX)
static char *addr4;
#endif

static size_t page_sz;

static struct test_case_t {
	char **addr;
	int flags;
	int exp_errno;
} test_cases[] = {
	{ &addr1, MS_INVALIDATE, EBUSY },
	{ &addr1, MS_ASYNC | MS_SYNC, EINVAL },
	{ &addr1, INV_SYNC, EINVAL },
	{ &addr2, MS_SYNC, EINVAL },
	{ &addr3, MS_SYNC, EINVAL },
#if !defined(UCLINUX)
	{ &addr4, MS_SYNC, ENOMEM },
#endif
};

static void msync_verify(struct test_case_t *tc);

char *TCID = "msync03";
int TST_TOTAL = ARRAY_SIZE(test_cases);

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

	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++)
			msync_verify(&test_cases[i]);
	}

	cleanup();
	tst_exit();
}

static void setup(void)
{
	size_t nwrite = 0;
	char write_buf[BUF_SIZE];
	struct rlimit rl;

	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	tst_tmpdir();

	TEST_PAUSE;

	page_sz = (size_t)sysconf(_SC_PAGESIZE);

	fd = SAFE_OPEN(cleanup, TEMPFILE, O_RDWR | O_CREAT, 0666);

	memset(write_buf, 'a', BUF_SIZE);
	while (nwrite < page_sz) {
		SAFE_WRITE(cleanup, 1, fd, write_buf, BUF_SIZE);
		nwrite += BUF_SIZE;
	}

	addr1 = SAFE_MMAP(cleanup, 0, page_sz, PROT_READ | PROT_WRITE,
			  MAP_SHARED | MAP_LOCKED, fd, 0);

	/* addr2 is not a multiple of PAGESIZE */
	addr2 = addr1 + 1;

	/* addr3 is outside the address space of the process */
	if (getrlimit(RLIMIT_DATA, &rl) < 0)
		tst_brkm(TBROK | TERRNO, NULL, "getrlimit failed");
	addr3 = (char *)rl.rlim_max;

#if !defined(UCLINUX)
	/* memory pointed to by addr4 was not mapped */
	addr4 = get_high_address();
#endif
}

static void msync_verify(struct test_case_t *tc)
{
	TEST(msync(*(tc->addr), page_sz, tc->flags));
	if (TEST_RETURN != -1) {
		tst_resm(TFAIL, "msync succeeded unexpectedly");
		return;
	}

	if (TEST_ERRNO == tc->exp_errno) {
		tst_resm(TPASS | TTERRNO, "msync failed as expected");
	} else {
		tst_resm(TFAIL | TTERRNO,
			 "msync failed unexpectedly; expected: "
			 "%d - %s", tc->exp_errno,
			 strerror(tc->exp_errno));
	}
}

static void cleanup(void)
{
	if (addr1 && munmap(addr1, page_sz) < 0)
		tst_resm(TWARN | TERRNO, "munmap() failed");

	if (fd > 0 && close(fd) < 0)
		tst_resm(TWARN | TERRNO, "close() failed");

	tst_rmdir();
}
