[LTP] [PATCH v2 6/6] kernel/syscalls/open14: openat03: add new test-cases
Alexey Kodanev
alexey.kodanev@oracle.com
Thu Jan 28 13:28:52 CET 2016
* create multiple directories and related temporary files;
* create multiple directories and link files into them. Check
that files permissions correspond to the ones specified with
open()/openat().
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
testcases/kernel/syscalls/open/open14.c | 163 ++++++++++++++++++++++++---
testcases/kernel/syscalls/openat/openat03.c | 160 ++++++++++++++++++++++++---
2 files changed, 294 insertions(+), 29 deletions(-)
diff --git a/testcases/kernel/syscalls/open/open14.c b/testcases/kernel/syscalls/open/open14.c
index 3784cb3..37a900a 100644
--- a/testcases/kernel/syscalls/open/open14.c
+++ b/testcases/kernel/syscalls/open/open14.c
@@ -21,6 +21,7 @@
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@@ -29,7 +30,8 @@
#include "lapi/fcntl.h"
char *TCID = "open14";
-int TST_TOTAL = 1;
+int TST_TOTAL = 3;
+
static const char *test_dir = ".";
static const ssize_t size = 1024;
static char buf[1024];
@@ -48,27 +50,36 @@ static void setup(void)
memset(buf, 1, size);
}
-void test01(void)
+static void create_file(const char *dir_name, int *fd, int mode)
{
- int fd, i;
+ *fd = open(dir_name, O_TMPFILE | O_RDWR, mode);
+ if (*fd != -1)
+ return;
- char path[PATH_MAX], tmp[PATH_MAX];
+ if (errno == EISDIR)
+ tst_brkm(TCONF, cleanup, "O_TMPFILE not supported");
- tst_resm(TINFO, "creating a file with O_TMPFILE flag");
+ tst_brkm(TFAIL | TERRNO, cleanup, "open() failed");
+}
- fd = open(test_dir, O_TMPFILE | O_WRONLY | O_SYNC);
- if (fd == -1) {
- if (errno == EISDIR) {
- tst_brkm(TCONF, cleanup,
- "O_TMPFILE not supported");
- }
- tst_resm(TFAIL | TERRNO, "open() failed");
- return;
- }
+static void write_file(int fd)
+{
+ int i;
- tst_resm(TINFO, "writing data to the file");
for (i = 0; i < blocks_num; ++i)
SAFE_WRITE(cleanup, 1, fd, buf, size);
+}
+
+void test01(void)
+{
+ int fd;
+ char path[PATH_MAX], tmp[PATH_MAX];
+
+ tst_resm(TINFO, "creating a file with O_TMPFILE flag");
+ create_file(test_dir, &fd, 0600);
+
+ tst_resm(TINFO, "writing data to the file");
+ write_file(fd);
SAFE_FSTAT(cleanup, fd, &st);
tst_resm(TINFO, "file size is '%zu'", st.st_size);
@@ -102,6 +113,126 @@ void test01(void)
tst_resm(TPASS, "test succeeded");
}
+static void read_file(int fd)
+{
+ int i;
+ char tmp[size];
+
+ SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
+
+ for (i = 0; i < blocks_num; ++i) {
+ SAFE_READ(cleanup, 0, fd, tmp, size);
+ if (strncmp(buf, tmp, size))
+ tst_brkm(TBROK, cleanup, "got unexepected data");
+ }
+}
+
+static void test02(void)
+{
+ const int files_num = 100;
+ int i, fd[files_num];
+ char path[PATH_MAX];
+
+ tst_resm(TINFO, "create files in multiple directories");
+ for (i = 0; i < files_num; ++i) {
+ snprintf(path, PATH_MAX, "tst02_%d", i);
+ SAFE_MKDIR(cleanup, path, 0700);
+ SAFE_CHDIR(cleanup, path);
+ SAFE_GETCWD(cleanup, path, PATH_MAX);
+ create_file(path, fd + i, 0600);
+ write_file(fd[i]);
+ }
+
+ tst_resm(TINFO, "removing test directories");
+ for (i = files_num - 1; i >= 0; --i) {
+ SAFE_CHDIR(cleanup, "../");
+ snprintf(path, PATH_MAX, "tst02_%d", i);
+ SAFE_RMDIR(cleanup, path);
+ }
+
+ tst_resm(TINFO, "writing/reading temporary files");
+ for (i = 0; i < files_num; ++i) {
+ write_file(fd[i]);
+ read_file(fd[i]);
+ }
+
+ tst_resm(TINFO, "closing temporary files");
+ for (i = 0; i < files_num; ++i)
+ SAFE_CLOSE(cleanup, fd[i]);
+
+ tst_resm(TPASS, "test succeeded");
+}
+
+static void link_tmp_file(int fd)
+{
+ char path1[PATH_MAX], path2[PATH_MAX];
+
+ snprintf(path1, PATH_MAX, "/proc/self/fd/%d", fd);
+ snprintf(path2, PATH_MAX, "tmpfile_%d", fd);
+
+ SAFE_LINKAT(cleanup, AT_FDCWD, path1, AT_FDCWD, path2,
+ AT_SYMLINK_FOLLOW);
+}
+
+static const int tst_perm[] = { 0, 07777, 001, 0755, 0644, 0440 };
+
+static void test03(void)
+{
+ const int files_num = 100;
+ int i, fd[files_num];
+ char path[PATH_MAX];
+ struct stat st;
+ unsigned int j;
+ mode_t mask = umask(0);
+
+ umask(mask);
+
+ tst_resm(TINFO, "create multiple directories, link files into them");
+ tst_resm(TINFO, "and check file permissions");
+ for (i = 0, j = 0; i < files_num; ++i) {
+
+ snprintf(path, PATH_MAX, "tst03_%d", i);
+ SAFE_MKDIR(cleanup, path, 0700);
+ SAFE_CHDIR(cleanup, path);
+ SAFE_GETCWD(cleanup, path, PATH_MAX);
+
+ create_file(path, fd + i, tst_perm[j]);
+ write_file(fd[i]);
+ read_file(fd[i]);
+
+ link_tmp_file(fd[i]);
+
+ snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
+
+ SAFE_LSTAT(cleanup, path, &st);
+
+ mode_t exp_mode = tst_perm[j] & ~mask;
+
+ if ((st.st_mode & ~S_IFMT) != exp_mode) {
+ tst_brkm(TFAIL, cleanup,
+ "file mode read %o, but expected %o",
+ st.st_mode & ~S_IFMT, exp_mode);
+ }
+
+ if (++j >= ARRAY_SIZE(tst_perm))
+ j = 0;
+ }
+
+ tst_resm(TINFO, "remove files, directories");
+ for (i = files_num - 1; i >= 0; --i) {
+ snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
+ SAFE_UNLINK(cleanup, path);
+ SAFE_CLOSE(cleanup, fd[i]);
+
+ SAFE_CHDIR(cleanup, "..");
+
+ snprintf(path, PATH_MAX, "tst03_%d", i);
+ SAFE_RMDIR(cleanup, path);
+ }
+
+ tst_resm(TPASS, "test passed");
+}
+
int main(int ac, char *av[])
{
int lc;
@@ -113,6 +244,8 @@ int main(int ac, char *av[])
for (lc = 0; TEST_LOOPING(lc); ++lc) {
tst_count = 0;
test01();
+ test02();
+ test03();
}
cleanup();
diff --git a/testcases/kernel/syscalls/openat/openat03.c b/testcases/kernel/syscalls/openat/openat03.c
index 3a0c2f1..743442c 100644
--- a/testcases/kernel/syscalls/openat/openat03.c
+++ b/testcases/kernel/syscalls/openat/openat03.c
@@ -21,6 +21,7 @@
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@@ -48,27 +49,36 @@ static void setup(void)
memset(buf, 1, size);
}
-void test01(void)
+static void create_file(const char *dir_name, int *fd, int mode)
{
- int fd, i;
+ *fd = openat(AT_FDCWD, dir_name, O_TMPFILE | O_RDWR, mode);
+ if (*fd != -1)
+ return;
- char path[PATH_MAX], tmp[PATH_MAX];
+ if (errno == EISDIR)
+ tst_brkm(TCONF, cleanup, "O_TMPFILE not supported");
- tst_resm(TINFO, "creating a file with O_TMPFILE flag");
+ tst_brkm(TFAIL | TERRNO, cleanup, "openat() failed");
+}
- fd = openat(AT_FDCWD, test_dir, O_TMPFILE | O_WRONLY | O_SYNC);
- if (fd == -1) {
- if (errno == EISDIR) {
- tst_brkm(TCONF, cleanup,
- "O_TMPFILE not supported");
- }
- tst_resm(TFAIL | TERRNO, "openat() failed");
- return;
- }
+static void write_file(int fd)
+{
+ int i;
- tst_resm(TINFO, "writing data to the file");
for (i = 0; i < blocks_num; ++i)
SAFE_WRITE(cleanup, 1, fd, buf, size);
+}
+
+void test01(void)
+{
+ int fd;
+ char path[PATH_MAX], tmp[PATH_MAX];
+
+ tst_resm(TINFO, "creating a file with O_TMPFILE flag");
+ create_file(test_dir, &fd, 0600);
+
+ tst_resm(TINFO, "writing data to the file");
+ write_file(fd);
SAFE_FSTAT(cleanup, fd, &st);
tst_resm(TINFO, "file size is '%zu'", st.st_size);
@@ -102,6 +112,126 @@ void test01(void)
tst_resm(TPASS, "test succeeded");
}
+static void read_file(int fd)
+{
+ int i;
+ char tmp[size];
+
+ SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
+
+ for (i = 0; i < blocks_num; ++i) {
+ SAFE_READ(cleanup, 0, fd, tmp, size);
+ if (strncmp(buf, tmp, size))
+ tst_brkm(TBROK, cleanup, "got unexepected data");
+ }
+}
+
+static void test02(void)
+{
+ const int files_num = 100;
+ int i, fd[files_num];
+ char path[PATH_MAX];
+
+ tst_resm(TINFO, "create files in multiple directories");
+ for (i = 0; i < files_num; ++i) {
+ snprintf(path, PATH_MAX, "tst02_%d", i);
+ SAFE_MKDIR(cleanup, path, 0700);
+ SAFE_CHDIR(cleanup, path);
+ SAFE_GETCWD(cleanup, path, PATH_MAX);
+ create_file(path, fd + i, 0600);
+ write_file(fd[i]);
+ }
+
+ tst_resm(TINFO, "removing test directories");
+ for (i = files_num - 1; i >= 0; --i) {
+ SAFE_CHDIR(cleanup, "../");
+ snprintf(path, PATH_MAX, "tst02_%d", i);
+ SAFE_RMDIR(cleanup, path);
+ }
+
+ tst_resm(TINFO, "writing/reading temporary files");
+ for (i = 0; i < files_num; ++i) {
+ write_file(fd[i]);
+ read_file(fd[i]);
+ }
+
+ tst_resm(TINFO, "closing temporary files");
+ for (i = 0; i < files_num; ++i)
+ SAFE_CLOSE(cleanup, fd[i]);
+
+ tst_resm(TPASS, "test succeeded");
+}
+
+static void link_tmp_file(int fd)
+{
+ char path1[PATH_MAX], path2[PATH_MAX];
+
+ snprintf(path1, PATH_MAX, "/proc/self/fd/%d", fd);
+ snprintf(path2, PATH_MAX, "tmpfile_%d", fd);
+
+ SAFE_LINKAT(cleanup, AT_FDCWD, path1, AT_FDCWD, path2,
+ AT_SYMLINK_FOLLOW);
+}
+
+static const int tst_perm[] = { 0, 07777, 001, 0755, 0644, 0440 };
+
+static void test03(void)
+{
+ const int files_num = 100;
+ int i, fd[files_num];
+ char path[PATH_MAX];
+ struct stat st;
+ unsigned int j;
+ mode_t mask = umask(0);
+
+ umask(mask);
+
+ tst_resm(TINFO, "create multiple directories, link files into them");
+ tst_resm(TINFO, "and check file permissions");
+ for (i = 0, j = 0; i < files_num; ++i) {
+
+ snprintf(path, PATH_MAX, "tst03_%d", i);
+ SAFE_MKDIR(cleanup, path, 0700);
+ SAFE_CHDIR(cleanup, path);
+ SAFE_GETCWD(cleanup, path, PATH_MAX);
+
+ create_file(path, fd + i, tst_perm[j]);
+ write_file(fd[i]);
+ read_file(fd[i]);
+
+ link_tmp_file(fd[i]);
+
+ snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
+
+ SAFE_LSTAT(cleanup, path, &st);
+
+ mode_t exp_mode = tst_perm[j] & ~mask;
+
+ if ((st.st_mode & ~S_IFMT) != exp_mode) {
+ tst_brkm(TFAIL, cleanup,
+ "file mode read %o, but expected %o",
+ st.st_mode & ~S_IFMT, exp_mode);
+ }
+
+ if (++j >= ARRAY_SIZE(tst_perm))
+ j = 0;
+ }
+
+ tst_resm(TINFO, "remove files, directories");
+ for (i = files_num - 1; i >= 0; --i) {
+ snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
+ SAFE_UNLINK(cleanup, path);
+ SAFE_CLOSE(cleanup, fd[i]);
+
+ SAFE_CHDIR(cleanup, "..");
+
+ snprintf(path, PATH_MAX, "tst03_%d", i);
+ SAFE_RMDIR(cleanup, path);
+ }
+
+ tst_resm(TPASS, "test passed");
+}
+
int main(int ac, char *av[])
{
int lc;
@@ -113,6 +243,8 @@ int main(int ac, char *av[])
for (lc = 0; TEST_LOOPING(lc); ++lc) {
tst_count = 0;
test01();
+ test02();
+ test03();
}
cleanup();
--
1.7.1
More information about the Ltp
mailing list