/*
 * Copyright (c) International Business Machines  Corp., 2001
 *	07/2001 Ported by Wayne Boyer
 *
 * 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
 */
/*
 * DESCRIPTION
 *	test 1:
 *	Read with an invalid file descriptor, and expect an EBADF.
 *
 *	test 2:
 *	The parameter passed to read is a directory, check if the errno is
 *	set to EISDIR.
 *
 *	test 3:
 *	Buf is outside the accessible address space, expect an EFAULT.
 *
 *	test 4:
 *	The file was opened with the O_DIRECT flag, and transfer sizes was not
 *	multiples of the logical block size of the file system, expect an
 *	EINVAL.
 *
 *	test 5:
 *	The file was opened with the O_DIRECT flag, and the alignment of the
 *	user buffer was not multiples of the logical block size of the file
 *	system, expect an EINVAL.
 */

#define _GNU_SOURCE

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "test.h"
#include "safe_macros.h"
#include "tst_fs_type.h"

char *TCID = "read02";

static int badfd = -1;
static int fd2, fd3, fd4 = -1;
static char buf[BUFSIZ];
static void *outside_buf = (void *)-1;
static void *addr4;
static void *addr5;

static long fs_type;

static struct test_case_t {
	int *fd;
	void **buf;
	size_t count;
	int exp_error;
} TC[] = {
	{&badfd, (void **)&buf, 1, EBADF},
	{&fd2, (void **)&buf, 1, EISDIR},
#ifndef UCLINUX
	{&fd3, &outside_buf, 1, EFAULT},
#endif
	{&fd4, &addr4, 1, EINVAL},
	{&fd4, &addr5, 4096, EINVAL},
};

int TST_TOTAL = ARRAY_SIZE(TC);
static void setup(void);
static void cleanup(void);
static void read_verify(const struct test_case_t *);

int main(int ac, char **av)
{
	int i;
	int 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++)
			read_verify(&TC[i]);
	}
	cleanup();
	tst_exit();
}

static void setup(void)
{
	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	TEST_PAUSE;

	tst_tmpdir();

	fd2 = SAFE_OPEN(cleanup, ".", O_DIRECTORY);

	SAFE_FILE_PRINTF(cleanup, "test_file", "A");

	fd3 = SAFE_OPEN(cleanup, "test_file", O_RDWR);

#if !defined(UCLINUX)
	outside_buf = SAFE_MMAP(cleanup, 0, 1, PROT_NONE,
				MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
#endif

	addr4 = SAFE_MEMALIGN(cleanup, getpagesize(), (4096 * 10));
	addr5 = addr4 + 1;

	fs_type = tst_fs_type(cleanup, ".");
	if (fs_type != TST_TMPFS_MAGIC)
		fd4 = SAFE_OPEN(cleanup, "test_file", O_RDWR | O_DIRECT);
}

static void read_verify(const struct test_case_t *test)
{
	if (test->fd == &fd4 && *test->fd == -1) {
		tst_resm(TCONF, "O_DIRECT not supported on %s filesystem",
		         tst_fs_type_name(fs_type));
		return;
	}

	TEST(read(*test->fd, *test->buf, test->count));

	if (*test->fd == fd4 && TEST_RETURN >= 0) {
		tst_resm(TPASS,
			 "O_DIRECT unaligned reads fallbacks to buffered I/O");
		return;
	}

	if (TEST_RETURN != -1) {
		tst_resm(TFAIL, "call succeeded unexpectedly");
		return;
	}

	if (TEST_ERRNO == test->exp_error) {
		tst_resm(TPASS | TTERRNO, "expected failure");
	} else {
		tst_resm(TFAIL | TTERRNO, "unexpected error expected %d",
			 test->exp_error);
	}
}

static void cleanup(void)
{
	free(addr4);

	if (fd4 > 0)
		close(fd4);

	if (fd3 > 0)
		close(fd3);

	if (fd2 > 0)
		close(fd2);

	tst_rmdir();
}
