[LTP] [PATCH] open14: Rewrite to new API

Martin Doucha mdoucha@suse.cz
Fri Jul 18 18:29:26 CEST 2025


Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
 testcases/kernel/syscalls/open/open14.c | 276 +++++++++++-------------
 1 file changed, 131 insertions(+), 145 deletions(-)

diff --git a/testcases/kernel/syscalls/open/open14.c b/testcases/kernel/syscalls/open/open14.c
index 3ecb7e4fb..41e274e69 100644
--- a/testcases/kernel/syscalls/open/open14.c
+++ b/testcases/kernel/syscalls/open/open14.c
@@ -1,63 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) 2015-2016 Oracle and/or its affiliates. All Rights Reserved.
- *
- * 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 would 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, see <http://www.gnu.org/licenses/>.
- *
  * Author: Alexey Kodanev <alexey.kodanev@oracle.com>
- *
+ * Copyright (c) 2025 SUSE LLC <mdoucha@suse.cz>
  */
 
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
+/*\
+ * Check the functionality of O_TMPFILE flag for open() syscall.
+ */
 
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
+#include "tst_safe_macros.h"
 #include "lapi/fcntl.h"
 
-char *TCID = "open14";
-int TST_TOTAL = 3;
-static ssize_t size;
+#define FILE_COUNT 100
+#define MNTPOINT "mntpoint"
+
 static char buf[1024];
+static int fds[FILE_COUNT];
+static const ssize_t size = sizeof(buf);
 static const ssize_t blocks_num = 4;
-static struct stat st;
-
-static void cleanup(void)
-{
-	tst_rmdir();
-}
 
 static void setup(void)
 {
-	tst_tmpdir();
+	int i;
 
-	size = sizeof(buf);
+	for (i = 0; i < FILE_COUNT; i++)
+		fds[i] = -1;
 
 	memset(buf, 1, size);
+	SAFE_CHDIR(MNTPOINT);
+	fds[0] = open(".", O_TMPFILE | O_RDWR, 0600);
 
-	int fd = open(".", O_TMPFILE | O_RDWR, 0600);
-
-	if (fd == -1) {
+	if (fds[0] == -1) {
 		if (errno == EISDIR || errno == ENOTSUP)
-			tst_brkm(TCONF, cleanup, "O_TMPFILE not supported");
+			tst_brk(TCONF, "O_TMPFILE not supported");
 
-		tst_brkm(TBROK | TERRNO, cleanup, "open() failed");
+		tst_brk(TBROK | TERRNO, "open() failed");
 	}
 
-	SAFE_CLOSE(cleanup, fd);
+	SAFE_CLOSE(fds[0]);
 }
 
 static void write_file(int fd)
@@ -65,183 +47,187 @@ static void write_file(int fd)
 	int i;
 
 	for (i = 0; i < blocks_num; ++i)
-		SAFE_WRITE(cleanup, SAFE_WRITE_ALL, fd, buf, size);
+		SAFE_WRITE(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");
-	fd = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR, 0600);
-
-	tst_resm(TINFO, "writing data to the file");
-	write_file(fd);
+	struct stat st;
+	char path[PATH_MAX];
 
-	SAFE_FSTAT(cleanup, fd, &st);
-	tst_resm(TINFO, "file size is '%li'", (long)st.st_size);
+	tst_res(TINFO, "Testing creation and linking of single temp file");
+	fds[0] = SAFE_OPEN(".", O_TMPFILE | O_RDWR, 0600);
+	write_file(fds[0]);
+	SAFE_FSTAT(fds[0], &st);
 
 	if (st.st_size != blocks_num * size) {
-		tst_resm(TFAIL, "not expected size: '%li' != '%zu'",
+		tst_res(TFAIL, "Unexpected test file size: %li != %zu",
 			 (long)st.st_size, blocks_num * size);
-		SAFE_CLOSE(cleanup, fd);
-		return;
+	} else {
+		tst_res(TPASS, "Test file size is %li", (long)st.st_size);
 	}
 
-	tst_resm(TINFO, "looking for the file in '.'");
-	if (!tst_dir_is_empty(cleanup, ".", 1))
-		tst_brkm(TFAIL, cleanup, "found a file, this is not expected");
-	tst_resm(TINFO, "file not found, OK");
+	if (!tst_dir_is_empty(".", 1))
+		tst_res(TFAIL, "Test directory is not empty");
+	else
+		tst_res(TPASS, "Test directory is empty");
 
-	snprintf(path, PATH_MAX,  "/proc/self/fd/%d", fd);
-	SAFE_READLINK(cleanup, path, tmp, PATH_MAX);
+	snprintf(path, PATH_MAX, "/proc/self/fd/%d", fds[0]);
+	tst_res(TINFO, "Linking unnamed test file to 'tmpfile'");
+	SAFE_LINKAT(AT_FDCWD, path, AT_FDCWD, "tmpfile", AT_SYMLINK_FOLLOW);
 
-	tst_resm(TINFO, "renaming '%s' -> 'tmpfile'", tmp);
-	SAFE_LINKAT(cleanup, AT_FDCWD, path, AT_FDCWD, "tmpfile",
-		    AT_SYMLINK_FOLLOW);
-
-	if (tst_dir_is_empty(cleanup, ".", 1))
-		tst_brkm(TFAIL, cleanup, "file not found");
+	if (tst_dir_is_empty(".", 1)) {
+		tst_res(TFAIL, "Test directory is still empty");
+		SAFE_CLOSE(fds[0]);
+		return;
+	}
 
-	SAFE_UNLINK(cleanup, "tmpfile");
-	SAFE_CLOSE(cleanup, fd);
+	if (access("tmpfile", F_OK)) {
+		tst_res(TFAIL | TERRNO, "Linked test file not found");
+		SAFE_CLOSE(fds[0]);
+		return;
+	}
 
-	tst_resm(TPASS, "single file tests passed");
+	tst_res(TPASS, "Test file was linked correctly");
+	SAFE_UNLINK("tmpfile");
+	SAFE_CLOSE(fds[0]);
 }
 
-static void read_file(int fd)
+static int read_file(int fd)
 {
 	int i;
 	char tmp[size];
 
-	SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
+	SAFE_LSEEK(fd, 0, SEEK_SET);
 
 	for (i = 0; i < blocks_num; ++i) {
-		SAFE_READ(cleanup, 0, fd, tmp, size);
-		if (memcmp(buf, tmp, size))
-			tst_brkm(TFAIL, cleanup, "got unexepected data");
+		SAFE_READ(0, fd, tmp, size);
+
+		if (memcmp(buf, tmp, size)) {
+			tst_res(TFAIL, "got unexepected data");
+			return 1;
+		}
 	}
+
+	return 0;
 }
 
 static void test02(void)
 {
-	const int files_num = 100;
-	int i, fd[files_num];
+	int i, fails = 0;
 	char path[PATH_MAX];
 
-	tst_resm(TINFO, "create files in multiple directories");
-	for (i = 0; i < files_num; ++i) {
+	tst_res(TINFO, "Testing temp files in multiple directories");
+	for (i = 0; i < FILE_COUNT; ++i) {
 		snprintf(path, PATH_MAX, "tst02_%d", i);
-		SAFE_MKDIR(cleanup, path, 0700);
-		SAFE_CHDIR(cleanup, path);
-
-		fd[i] = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR, 0600);
+		SAFE_MKDIR(path, 0700);
+		SAFE_CHDIR(path);
+		fds[i] = SAFE_OPEN(".", O_TMPFILE | O_RDWR, 0600);
 	}
 
-	tst_resm(TINFO, "removing test directories");
-	for (i = files_num - 1; i >= 0; --i) {
-		SAFE_CHDIR(cleanup, "..");
+	tst_res(TINFO, "Removing test directories");
+	for (i = FILE_COUNT - 1; i >= 0; --i) {
+		SAFE_CHDIR("..");
 		snprintf(path, PATH_MAX, "tst02_%d", i);
-		SAFE_RMDIR(cleanup, path);
+		SAFE_RMDIR(path);
 	}
 
-	tst_resm(TINFO, "writing/reading temporary files");
-	for (i = 0; i < files_num; ++i) {
-		write_file(fd[i]);
-		read_file(fd[i]);
+	tst_res(TINFO, "Writing and reading temporary files");
+	for (i = 0; i < FILE_COUNT; ++i) {
+		write_file(fds[i]);
+		fails += read_file(fds[i]);
 	}
 
-	tst_resm(TINFO, "closing temporary files");
-	for (i = 0; i < files_num; ++i)
-		SAFE_CLOSE(cleanup, fd[i]);
+	tst_res(TINFO, "Closing temporary files");
+	for (i = 0; i < FILE_COUNT; ++i)
+		SAFE_CLOSE(fds[i]);
 
-	tst_resm(TPASS, "multiple files tests passed");
+	if (!fails)
+		tst_res(TPASS, "Multiple files test passed");
 }
 
 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);
+	snprintf(path1, PATH_MAX, "/proc/self/fd/%d", fd);
+	snprintf(path2, PATH_MAX, "tmpfile_%d", fd);
+	SAFE_LINKAT(AT_FDCWD, path1, AT_FDCWD, path2, AT_SYMLINK_FOLLOW);
 }
 
 static void test03(void)
 {
-	const int files_num = 100;
 	const mode_t test_perms[] = { 0, 07777, 001, 0755, 0644, 0440 };
 
-	int i, fd[files_num];
+	int i, fails = 0;
 	char path[PATH_MAX];
 	struct stat st;
 	mode_t mask = umask(0), perm;
 
 	umask(mask);
+	tst_res(TINFO, "Testing linked temp files access mode");
 
-	tst_resm(TINFO, "create multiple directories, link files into them");
-	tst_resm(TINFO, "and check file permissions");
-	for (i = 0; i < files_num; ++i) {
-
+	for (i = 0; i < FILE_COUNT; ++i) {
 		snprintf(path, PATH_MAX, "tst03_%d", i);
-		SAFE_MKDIR(cleanup, path, 0700);
-		SAFE_CHDIR(cleanup, path);
+		SAFE_MKDIR(path, 0700);
+		SAFE_CHDIR(path);
 
 		perm = test_perms[i % ARRAY_SIZE(test_perms)];
-
-		fd[i] = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR, perm);
-
-		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 = perm & ~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);
+		fds[i] = SAFE_OPEN(".", O_TMPFILE | O_RDWR, perm);
+		write_file(fds[i]);
+		read_file(fds[i]);
+		link_tmp_file(fds[i]);
+
+		snprintf(path, PATH_MAX, "tmpfile_%d", fds[i]);
+		SAFE_LSTAT(path, &st);
+		perm &= ~mask;
+
+		if ((st.st_mode & ~S_IFMT) != perm) {
+			tst_res(TFAIL, "Unexpected access mode: %04o != %04o",
+				st.st_mode & ~S_IFMT, perm);
+			fails++;
 		}
 	}
 
-	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]);
+	if (!fails)
+		tst_res(TPASS, "File access modes are correct");
+
+	tst_res(TINFO, "Removing files and directories");
 
-		SAFE_CHDIR(cleanup, "..");
+	for (i = FILE_COUNT - 1; i >= 0; --i) {
+		snprintf(path, PATH_MAX, "tmpfile_%d", fds[i]);
+		SAFE_UNLINK(path);
+		SAFE_CLOSE(fds[i]);
 
+		SAFE_CHDIR("..");
 		snprintf(path, PATH_MAX, "tst03_%d", i);
-		SAFE_RMDIR(cleanup, path);
+		SAFE_RMDIR(path);
 	}
-
-	tst_resm(TPASS, "file permission tests passed");
 }
 
-int main(int ac, char *av[])
+static void run(void)
 {
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
+	test01();
+	test02();
+	test03();
+}
 
-	setup();
+static void cleanup(void)
+{
+	int i;
 
-	for (lc = 0; TEST_LOOPING(lc); ++lc) {
-		tst_count = 0;
-		test01();
-		test02();
-		test03();
+	for (i = 0; i < FILE_COUNT; i++) {
+		if (fds[i] >= 0)
+			SAFE_CLOSE(fds[i]);
 	}
 
-	cleanup();
-	tst_exit();
+	SAFE_CHDIR("..");
 }
+
+static struct tst_test test = {
+	.setup = setup,
+	.test_all = run,
+	.cleanup = cleanup,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1
+};
-- 
2.50.1



More information about the ltp mailing list