[LTP] [PATCH v2] kernel/syscalls/open14: openat03: add new test-cases

Alexey Kodanev alexey.kodanev@oracle.com
Mon Jan 25 09:17:49 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>
---
v2: don't remove 'openat.h' include from openat03.c

 testcases/kernel/syscalls/open/open14.c     |  159 ++++++++++++++++++++++++--
 testcases/kernel/syscalls/openat/openat03.c |  159 ++++++++++++++++++++++++--
 2 files changed, 292 insertions(+), 26 deletions(-)

diff --git a/testcases/kernel/syscalls/open/open14.c b/testcases/kernel/syscalls/open/open14.c
index 839c898..0984bfd 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>
 
@@ -32,7 +33,7 @@
 #endif
 
 char *TCID = "open14";
-int TST_TOTAL = 1;
+int TST_TOTAL = 3;
 static char *test_dir;
 static ssize_t size;
 static const ssize_t blocks_num = 4;
@@ -79,28 +80,38 @@ static int dir_not_empty(void)
 	return ret;
 }
 
-void test01(void)
+static void create_file(char *dir_name, int *fd, int mode)
 {
-	int fd, i;
-
-	char path[PATH_MAX], tmp[PATH_MAX];
-
-	tst_resm(TINFO, "creating a file with O_TMPFILE flag");
-
-	TEST(open(test_dir, O_TMPFILE | O_WRONLY | O_SYNC));
-	fd = TEST_RETURN;
-	if (fd == -1) {
+	TEST(open(dir_name, O_TMPFILE | O_RDWR, mode));
+	*fd = TEST_RETURN;
+	if (*fd == -1) {
 		if (TEST_ERRNO == EISDIR) {
 			tst_brkm(TCONF, cleanup,
 				"O_TMPFILE not supported");
 		}
-		tst_resm(TFAIL | TERRNO, "open() failed");
+		tst_brkm(TFAIL | TERRNO, cleanup, "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, 0, 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);
@@ -135,6 +146,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);
+
+	if (linkat(AT_FDCWD, path1, AT_FDCWD, path2, AT_SYMLINK_FOLLOW))
+		tst_brkm(TBROK | TERRNO, cleanup, "linkat() failed");
+}
+
+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;
@@ -146,6 +277,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 d81989e..28bf5eb 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>
 
@@ -33,7 +34,7 @@
 #endif
 
 char *TCID = "openat03";
-int TST_TOTAL = 1;
+int TST_TOTAL = 3;
 static char *test_dir;
 static ssize_t size;
 static const ssize_t blocks_num = 4;
@@ -80,28 +81,38 @@ static int dir_not_empty(void)
 	return ret;
 }
 
-void test01(void)
+static void create_file(char *dir_name, int *fd, int mode)
 {
-	int fd, i;
-
-	char path[PATH_MAX], tmp[PATH_MAX];
-
-	tst_resm(TINFO, "creating a file with O_TMPFILE flag");
-
-	TEST(openat(AT_FDCWD, test_dir, O_TMPFILE | O_WRONLY | O_SYNC));
-	fd = TEST_RETURN;
-	if (fd == -1) {
+	TEST(openat(AT_FDCWD, dir_name, O_TMPFILE | O_RDWR, mode));
+	*fd = TEST_RETURN;
+	if (*fd == -1) {
 		if (TEST_ERRNO == EISDIR) {
 			tst_brkm(TCONF, cleanup,
 				"O_TMPFILE not supported");
 		}
-		tst_resm(TFAIL | TERRNO, "openat() failed");
+		tst_brkm(TFAIL | TERRNO, cleanup, "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, 0, 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);
@@ -136,6 +147,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);
+
+	if (linkat(AT_FDCWD, path1, AT_FDCWD, path2, AT_SYMLINK_FOLLOW))
+		tst_brkm(TBROK | TERRNO, cleanup, "linkat() failed");
+}
+
+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;
@@ -147,6 +278,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