Add new tests for open(2) O_APPEND O_CLOEXEC O_NOATIME O_LARGEFILE Signed-off-by: Zeng Linggang <[email protected]> --- runtest/ltplite | 1 + runtest/stress.part3 | 1 + runtest/syscalls | 1 + testcases/kernel/syscalls/.gitignore | 1 + testcases/kernel/syscalls/open/open12.c | 255 ++++++++++++++++++++++++ testcases/kernel/syscalls/open/open12_cloexec.c | 35 ++++ 6 files changed, 294 insertions(+) create mode 100644 testcases/kernel/syscalls/open/open12.c create mode 100644 testcases/kernel/syscalls/open/open12_cloexec.c
diff --git a/runtest/ltplite b/runtest/ltplite index f7127fe..73cd781 100644 --- a/runtest/ltplite +++ b/runtest/ltplite @@ -543,6 +543,7 @@ open08 open08 open09 open09 open10 open10 open11 open11 +open12 open12 -F open12_cloexec mincore01 mincore01 #mincore02 mincore02 currently hangs and does not exit correctly diff --git a/runtest/stress.part3 b/runtest/stress.part3 index 2f31e93..14ee681 100644 --- a/runtest/stress.part3 +++ b/runtest/stress.part3 @@ -465,6 +465,7 @@ open08 open08 open09 open09 open10 open10 open11 open11 +open12 open12 -F open12_cloexec pathconf01 pathconf01 diff --git a/runtest/syscalls b/runtest/syscalls index 2a408c4..c15caeb 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -702,6 +702,7 @@ open08 open08 open09 open09 open10 open10 open11 open11 +open12 open12 -F open12_cloexec #openat test cases openat01 openat01 diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore index 0138ba9..d336772 100644 --- a/testcases/kernel/syscalls/.gitignore +++ b/testcases/kernel/syscalls/.gitignore @@ -596,6 +596,7 @@ /open/open09 /open/open10 /open/open11 +/open/open12 /openat/openat01 /pathconf/pathconf01 /pause/pause01 diff --git a/testcases/kernel/syscalls/open/open12.c b/testcases/kernel/syscalls/open/open12.c new file mode 100644 index 0000000..a24723e --- /dev/null +++ b/testcases/kernel/syscalls/open/open12.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2014 Fujitsu Ltd. + * Author: Zeng Linggang <[email protected]> + * + * 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. + */ +/* + * DESCRIPTION + * This test case will verify basic function of open(2) with the flags + * O_APPEND, O_CLOEXEC and O_NOATIME. + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <mntent.h> +#include <errno.h> +#include "test.h" +#include "usctest.h" +#include "safe_macros.h" +#include "lapi/fcntl.h" + +#define TEST_FILE "test_file" + +char *TCID = "open12"; + +static int fd; +static char *test_subexe; +static char *device; +static char test_path[MAXPATHLEN]; +static char test_path2[MAXPATHLEN]; +static void setup(void); +static void cleanup(void); +static void test_append(void); +static void test_noatime(void); +static void test_cloexec(void); +static void test_largefile(void); +static void help(void); +static option_t options[] = { + {"F:", NULL, &test_subexe}, + {"D:", NULL, &device}, + {NULL, NULL, NULL} +}; + +static void (*test_func[])(void) = { test_append, test_noatime, test_cloexec, + test_largefile }; + +int TST_TOTAL = ARRAY_SIZE(test_func); + +int main(int argc, char **argv) +{ + int lc; + char *msg; + int i; + + msg = parse_opts(argc, argv, options, &help); + if (msg != NULL) + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); + + if (!test_subexe) { + tst_brkm(TBROK, NULL, + "You must specify a test executable with the -F option."); + } + + setup(); + + for (lc = 0; TEST_LOOPING(lc); lc++) { + tst_count = 0; + for (i = 0; i < TST_TOTAL; i++) + (*test_func[i])(); + } + + cleanup(); + tst_exit(); +} + +static void setup(void) +{ + tst_require_root(NULL); + + TEST_PAUSE; + + tst_sig(FORK, DEF_HANDLER, cleanup); + + if (test_subexe[0] != '/') { + sprintf(test_path, "%s/%s", get_current_dir_name(), + basename(test_subexe)); + test_subexe = test_path; + } + + if (device != NULL && device[0] != '/') { + sprintf(test_path2, "%s/%s", get_current_dir_name(), + basename(device)); + device = test_path2; + } + + tst_tmpdir(); + + SAFE_FILE_PRINTF(cleanup, TEST_FILE, TEST_FILE); +} + +static void test_append(void) +{ + unsigned int len; + + fd = SAFE_OPEN(cleanup, TEST_FILE, O_APPEND | O_RDWR); + + SAFE_WRITE(cleanup, 1, fd, TEST_FILE, sizeof(TEST_FILE)); + len = SAFE_LSEEK(cleanup, fd, 0, SEEK_CUR); + SAFE_CLOSE(cleanup, fd); + + if (len > sizeof(TEST_FILE)) + tst_resm(TPASS, "open(%s, O_APPEND) test success", TEST_FILE); + else + tst_resm(TFAIL, "open(%s, O_APPEND) test failed", TEST_FILE); +} + +static void test_noatime(void) +{ + FILE *mtab_f; + struct mntent *entry; + char read_buf; + struct stat orignal, flag, no_flag; + + if ((tst_kvercmp(2, 6, 9)) < 0) { + tst_resm(TCONF, + "O_NOATIME flags test for open(2) needs kernel 2.6.9 " + "or higher"); + return; + } + + mtab_f = setmntent("/etc/mtab", "r"); + entry = getmntent(mtab_f); + if (hasmntopt(entry, "noatime") != NULL || + hasmntopt(entry, "relatime") != NULL) { + tst_resm(TCONF, + "O_NOATIME flags test for open(2) needs filesystems " + "which are mounted without noatime and relatime"); + return; + } + endmntent(mtab_f); + + SAFE_STAT(cleanup, TEST_FILE, &orignal); + + sleep(1); + + fd = SAFE_OPEN(cleanup, TEST_FILE, O_RDONLY | O_NOATIME); + SAFE_READ(cleanup, 1, fd, &read_buf, 1); + SAFE_CLOSE(cleanup, fd); + SAFE_STAT(cleanup, TEST_FILE, &flag); + + fd = SAFE_OPEN(cleanup, TEST_FILE, O_RDONLY); + SAFE_READ(cleanup, 1, fd, &read_buf, 1); + SAFE_CLOSE(cleanup, fd); + SAFE_STAT(cleanup, TEST_FILE, &no_flag); + + if (orignal.st_atime == flag.st_atime && + orignal.st_atime != no_flag.st_atime) + tst_resm(TPASS, "open(%s, O_NOATIME) test success", TEST_FILE); + else + tst_resm(TFAIL, "open(%s, O_NOATIME) test failed", TEST_FILE); +} + +static void test_cloexec(void) +{ + int fd2; + pid_t pid; + int status; + char buf[20]; + + if ((tst_kvercmp(2, 6, 24)) < 0) { + tst_resm(TCONF, + "O_CLOEXEC flags test for open(2) needs kernel 2.6.24 " + "or higher"); + return; + } + + fd2 = SAFE_OPEN(cleanup, TEST_FILE, O_RDWR | O_APPEND | O_CLOEXEC); + + sprintf(buf, "%d", fd2); + pid = tst_fork(); + if (pid < 0) + tst_brkm(TBROK, cleanup, "fork() failed"); + + if (pid == 0) { + if (execl(test_subexe, "open12_cloexec", buf, NULL)) { + printf("execl error\n"); + exit(-2); + } + } + + SAFE_CLOSE(cleanup, fd2); + + if (wait(&status) != pid) + printf("wait error\n"); + + if (WIFEXITED(status) && (char)WEXITSTATUS(status) == -1) + tst_resm(TPASS, "open(%s, O_CLOEXEC) test success", TEST_FILE); + else + tst_resm(TFAIL, "open(%s, O_CLOEXEC) test failed", TEST_FILE); +} + +static void test_largefile(void) +{ + struct stat buf; + + if (!device) { + tst_resm(TCONF, + "O_LARGEFILE flags test for open(2) needs specify the " + "-D option."); + return; + } + + SAFE_STAT(cleanup, device, &buf); + if (buf.st_size < 4L * 1024 * 1024 * 1024) { + tst_resm(TCONF, + "O_LARGEFILE flags test for open(2) needs the file " + "which size is more than 4G."); + return; + } + + TEST(open(device, O_RDONLY | O_LARGEFILE)); + SAFE_CLOSE(cleanup, TEST_RETURN); + + if (TEST_RETURN != -1) { + tst_resm(TPASS, "open(%s, O_LARGEFILE) test success", device); + } else { + tst_resm(TFAIL | TTERRNO, + "open(%s, O_LARGEFILE) failed unexpectedly", device); + } +} + +static void cleanup(void) +{ + TEST_CLEANUP; + + tst_rmdir(); +} + +static void help(void) +{ + printf(" -F <test file> : for example, 'open12 -F open12_cloexec'\n"); +} diff --git a/testcases/kernel/syscalls/open/open12_cloexec.c b/testcases/kernel/syscalls/open/open12_cloexec.c new file mode 100644 index 0000000..e06d7d3 --- /dev/null +++ b/testcases/kernel/syscalls/open/open12_cloexec.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014 Fujitsu Ltd. + * Author: Zeng Linggang <[email protected]> + * + * 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> + +int main(int argc, char **argv) +{ + int ret; + int fd; + + if (argc != 2) + printf("Only two arguments: %s <fd>", argv[0]); + + fd = atoi(argv[1]); + ret = write(fd, argv[1], strlen(argv[1])); + + exit(ret); +} -- 1.8.4.2 ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/13534_NeoTech _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
