[LTP] [PATCH] read/read02.c: add new error number tests

Zeng Linggang
2014-03-28T07:22:32Z

Add EINVAL errnor nuber tests for read(2):
* 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.

* 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.

Signed-off-by: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
---
testcases/kernel/syscalls/read/read02.c | 53 ++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 7 deletions(-)

diff --git a/testcases/kernel/syscalls/read/read02.c b/testcases/kernel/syscalls/read/read02.c
index 8aabe93..0e227fe 100644
--- a/testcases/kernel/syscalls/read/read02.c
+++ b/testcases/kernel/syscalls/read/read02.c
@@ -27,6 +27,16 @@
*
* test 3:
* Pass buf = -1 as a parmeter to read, expect an EFAULT.
+ *
+ * test 4:
+ * 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.
+ *
+ * test 5:
+ * 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.
*/

#define _GNU_SOURCE
@@ -41,22 +51,30 @@
#include "safe_macros.h"

#define TEST_FILE "test_file"
+#define TEST_FILE4 "/root/test_file4"

char *TCID = "read02";

static int badfd = -1;
-static int fd2, fd3;
+static int fd2, fd3, fd4;
static char buf[BUFSIZ];
-static int exp_enos[] = { EBADF, EISDIR, EFAULT, 0 };
+static void *outside_buf = (void *)-1;
+static void *temp;
+static void *addr4;
+static void *addr5;
+static int exp_enos[] = { EBADF, EISDIR, EFAULT, EINVAL, 0 };

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

int TST_TOTAL = ARRAY_SIZE(TC);
@@ -89,6 +107,11 @@ int main(int ac, char **av)

static void setup(void)
{
+ if ((tst_kvercmp(2, 4, 10)) < 0)
+ tst_brkm(TCONF, NULL, "This test needs kernel 2.4.10 or newer");
+
+ tst_require_root(NULL);
+
tst_sig(NOFORK, DEF_HANDLER, cleanup);

TEST_PAUSE;
@@ -100,11 +123,19 @@ static void setup(void)
SAFE_FILE_PRINTF(cleanup, TEST_FILE, "A");

fd3 = SAFE_OPEN(cleanup, TEST_FILE, O_RDWR | O_CREAT, 0666);
+
+ temp = SAFE_MALLOC(cleanup, 4096*10);
+
+ addr4 = (char *)(((long)buf & (~4095)) + 1);
+ addr5 = (char *)((long)buf & (~4095));
+
+ SAFE_FILE_PRINTF(cleanup, TEST_FILE4, "A");
+ fd4 = SAFE_OPEN(cleanup, TEST_FILE4, O_RDWR | O_DIRECT, 0777);
}

static void read_verify(const struct test_case_t *test)
{
- TEST(read(*test->fd, test->buf, 1));
+ TEST(read(*test->fd, *test->buf, test->count));

if (TEST_RETURN != -1) {
tst_resm(TFAIL, "call succeeded unexpectedly");
@@ -127,6 +158,14 @@ static void cleanup(void)
{
TEST_CLEANUP;

+ free(temp);
+
+ if (fd4 > 0)
+ close(fd4);
+
+ if (unlink(TEST_FILE4) < 0)
+ tst_resm(TWARN | TERRNO, "unlink(\"%s\") failed", TEST_FILE4);
+
if (fd3 > 0)
close(fd3);

--
1.8.4.2