All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v2 0/6] Rewrite fs stream testing suite
@ 2026-03-04 13:25 Andrea Cervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 1/6] Add safe macros for " Andrea Cervesato
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-03-04 13:25 UTC (permalink / raw)
  To: Linux Test Project

All tests are now using the new LTP API. The stream05 has been deleted
because I think it was a bit messy and it didn't have a proper testing
focus. I replaced it with a new test that is just verifying that fd
returned by `fileno()` can be used for basic operations on fd.

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Changes in v2:
- add SAFE_FFLUSH() macro
- remove cleanup_fn from SAFE_* macros
- stream01: use a double buffer to write data inside file
- stream02: check if stream is NULL after fopen()
- stream05: use SAFE_FFLUSH()
- stream05: don't overengineer SAFE_FILENO() with TST_EXP_FD()
- Link to v1: https://lore.kernel.org/r/20260123-stream_refactoring-v1-0-281b85f6ab02@suse.com

---
Andrea Cervesato (6):
      Add safe macros for stream testing suite
      fs: rewrite stream01 test using new API
      fs: rewrite stream02 test using new API
      fs: rewrite stream03 test using new API
      fs: rewrite stream04 test using new API
      fs: rewrite stream05 test using new API

 include/safe_stdio_fn.h               |  21 +++
 include/tst_safe_stdio.h              |  21 +++
 lib/safe_stdio.c                      | 101 +++++++++++
 testcases/kernel/fs/stream/stream01.c | 155 +++++-----------
 testcases/kernel/fs/stream/stream02.c | 136 ++++----------
 testcases/kernel/fs/stream/stream03.c | 326 ++++++----------------------------
 testcases/kernel/fs/stream/stream04.c | 147 +++++----------
 testcases/kernel/fs/stream/stream05.c | 258 +++++----------------------
 8 files changed, 362 insertions(+), 803 deletions(-)
---
base-commit: 23ea0f0f8064f68bbf4d5c5f4f037ef18a5848d8
change-id: 20260120-stream_refactoring-4b5a6e9d0ad7

Best regards,
-- 
Andrea Cervesato <andrea.cervesato@suse.com>


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [LTP] [PATCH v2 1/6] Add safe macros for stream testing suite
  2026-03-04 13:25 [LTP] [PATCH v2 0/6] Rewrite fs stream testing suite Andrea Cervesato
@ 2026-03-04 13:25 ` Andrea Cervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 2/6] fs: rewrite stream01 test using new API Andrea Cervesato
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-03-04 13:25 UTC (permalink / raw)
  To: Linux Test Project

From: Andrea Cervesato <andrea.cervesato@suse.com>

Introduce the following SAFE_* macros for stream file testing:

- SAFE_FREAD
- SAFE_FWRITE
- SAFE_FREOPEN
- SAFE_FSEEK
- SAFE_FTELL
- SAFE_FILENO
- SAFE_FFLUSH

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 include/safe_stdio_fn.h  |  21 ++++++++++
 include/tst_safe_stdio.h |  21 ++++++++++
 lib/safe_stdio.c         | 101 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+)

diff --git a/include/safe_stdio_fn.h b/include/safe_stdio_fn.h
index 3818a86571a6d9bc63fcf432c93683bb3298e5b2..255a85949749748533e93b86c7cf170900e95082 100644
--- a/include/safe_stdio_fn.h
+++ b/include/safe_stdio_fn.h
@@ -32,4 +32,25 @@ int safe_asprintf(const char *file, const int lineno, void (cleanup_fn)(void),
 FILE *safe_popen(const char *file, const int lineno, void (cleanup_fn)(void),
 		 const char *command, const char *type);
 
+size_t safe_fread(const char *file, const int lineno,
+		  void *ptr, size_t size, size_t n, FILE *stream);
+
+size_t safe_fwrite(const char *file, const int lineno,
+		   const void *ptr, size_t size, size_t n, FILE *stream);
+
+FILE *safe_freopen(const char *file, const int lineno,
+		   const char *path, const char *mode, FILE *stream);
+
+int safe_fseek(const char *file, const int lineno,
+	       FILE *f, long offset, int whence);
+
+long safe_ftell(const char *file, const int lineno,
+		FILE *f);
+
+int safe_fileno(const char *file, const int lineno,
+		FILE *stream);
+
+int safe_fflush(const char *file, const int lineno,
+		FILE *stream);
+
 #endif /* SAFE_STDIO_FN_H__ */
diff --git a/include/tst_safe_stdio.h b/include/tst_safe_stdio.h
index e4bff34da15c9116809fcf851cbf544a51e384ef..45d4bc7e5d590468eec7a95b0aa37019e4e15f18 100644
--- a/include/tst_safe_stdio.h
+++ b/include/tst_safe_stdio.h
@@ -21,4 +21,25 @@
 #define SAFE_POPEN(command, type) \
 	safe_popen(__FILE__, __LINE__, NULL, command, type)
 
+#define SAFE_FREAD(ptr, size, n, stream) \
+	safe_fread(__FILE__, __LINE__, ptr, size, n, stream)
+
+#define SAFE_FWRITE(ptr, size, n, stream) \
+	safe_fwrite(__FILE__, __LINE__, ptr, size, n, stream)
+
+#define SAFE_FREOPEN(path, mode, stream) \
+	safe_freopen(__FILE__, __LINE__, path, mode, stream)
+
+#define SAFE_FSEEK(f, offset, whence) \
+	safe_fseek(__FILE__, __LINE__, f, offset, whence)
+
+#define SAFE_FTELL(f) \
+	safe_ftell(__FILE__, __LINE__, f)
+
+#define SAFE_FILENO(f) \
+	safe_fileno(__FILE__, __LINE__, f)
+
+#define SAFE_FFLUSH(f) \
+	safe_fflush(__FILE__, __LINE__, f)
+
 #endif /* TST_SAFE_STDIO_H__ */
diff --git a/lib/safe_stdio.c b/lib/safe_stdio.c
index ab23e43bb0835cdca5eaa015bc873fd23f9a8408..feb8a4b5c87c8b2cb7f7f59f6ba763e45acdf237 100644
--- a/lib/safe_stdio.c
+++ b/lib/safe_stdio.c
@@ -99,3 +99,104 @@ FILE *safe_popen(const char *file, const int lineno, void (cleanup_fn)(void),
 
 	return stream;
 }
+
+size_t safe_fread(const char *file, const int lineno,
+	void *ptr, size_t size, size_t n, FILE *stream)
+{
+	size_t ret;
+
+	ret = fread(ptr, size, n, stream);
+	if (ret != n) {
+		tst_brkm_(file, lineno, TBROK, NULL,
+			"fread(%p, %lu, %lu, %p) read %lu bytes",
+			ptr, size, n, stream, ret);
+	}
+
+	return ret;
+}
+
+size_t safe_fwrite(const char *file, const int lineno,
+	const void *ptr, size_t size, size_t n, FILE *stream)
+{
+	size_t ret;
+
+	ret = fwrite(ptr, size, n, stream);
+	if (ret != n) {
+		tst_brkm_(file, lineno, TBROK, NULL,
+			"fwrite(%p, %lu, %lu, %p) written %lu bytes",
+			ptr, size, n, stream, ret);
+	}
+
+	return ret;
+}
+
+FILE *safe_freopen(const char *file, const int lineno,
+	       const char *path, const char *mode, FILE *stream)
+{
+	FILE *f = freopen(path, mode, stream);
+
+	if (!f) {
+		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
+			"freopen(%s,%s,%p) failed", path, mode, stream);
+	}
+
+	return f;
+}
+
+int safe_fseek(const char *file, const int lineno,
+		   FILE *f, long offset, int whence)
+{
+	int ret;
+
+	errno = 0;
+	ret = fseek(f, offset, whence);
+
+	if (ret == -1) {
+		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
+			"fseek(%p, %ld, %d)", f, offset, whence);
+	}
+
+	return ret;
+}
+
+long safe_ftell(const char *file, const int lineno,
+	       FILE *f)
+{
+	long ret;
+
+	errno = 0;
+	ret = ftell(f);
+
+	if (ret == -1)
+		tst_brkm_(file, lineno, TBROK | TERRNO, NULL, "ftell(%p)", f);
+
+	return ret;
+}
+
+int safe_fileno(const char *file, const int lineno,
+		FILE *f)
+{
+	int ret;
+
+	errno = 0;
+	ret = fileno(f);
+
+	if (ret == -1)
+		tst_brkm_(file, lineno, TBROK | TERRNO, NULL, "fileno(%p)", f);
+
+	return ret;
+}
+
+int safe_fflush(const char *file, const int lineno,
+		FILE *f)
+{
+	int ret;
+
+	errno = 0;
+	ret = fflush(f);
+
+	if (ret == EOF)
+		tst_brkm_(file, lineno, TBROK | TERRNO, NULL, "fflush(%p)", f);
+
+	return ret;
+}

-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH v2 2/6] fs: rewrite stream01 test using new API
  2026-03-04 13:25 [LTP] [PATCH v2 0/6] Rewrite fs stream testing suite Andrea Cervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 1/6] Add safe macros for " Andrea Cervesato
@ 2026-03-04 13:25 ` Andrea Cervesato
  2026-04-07 14:57   ` Cyril Hrubis
  2026-04-10 15:00   ` [LTP] Add safe macros for stream testing suite acervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 3/6] fs: rewrite stream02 test using new API Andrea Cervesato
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-03-04 13:25 UTC (permalink / raw)
  To: Linux Test Project

From: Andrea Cervesato <andrea.cervesato@suse.com>

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/fs/stream/stream01.c | 155 +++++++++++-----------------------
 1 file changed, 49 insertions(+), 106 deletions(-)

diff --git a/testcases/kernel/fs/stream/stream01.c b/testcases/kernel/fs/stream/stream01.c
index af56bca3b916c080328c3356681efbd869b961d2..d666e67491e53b1c45dabef5bb6118dbbdc8ad38 100644
--- a/testcases/kernel/fs/stream/stream01.c
+++ b/testcases/kernel/fs/stream/stream01.c
@@ -1,127 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
+ * Copyright (c) International Business Machines  Corp., 2002
+ *	ported from SPIE section2/filesuite/stream1.c, by Airong Zhang
  *
- *   Copyright (c) International Business Machines  Corp., 2002
- *
- *   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.
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Verify that `freopen()` substitutes the named file in place of stream.
  *
- *   This program is distributed in the hope that it will 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.
+ * [Algorithm]
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * - fopen() a stream
+ * - fwrite() something inside it
+ * - perform freopen() creating a new stream pointing to the first one
+ * - fwrite() data inside the new stream
+ * - check that second write to stream went to the file specified by freopen()
  */
 
-/* ported from SPIE section2/filesuite/stream1.c, by Airong Zhang */
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
 
-/*======================================================================
-	=================== TESTPLAN SEGMENT ===================
->KEYS:  < freopen()
->WHAT:  < 1) check that freopen substitutes the named file in place of stream.
->HOW:   < 1) open a stream, write something to it, perform freopen and
-	<    write some more. Check that second write to stream went to
-	<    the file specified by freopen.
->BUGS:  <
-======================================================================*/
+#define FILENAME1 "ltp_file1.txt"
+#define FILENAME2 "ltp_file2.txt"
 
-#include <stdio.h>
-#include <errno.h>
-#include "test.h"
+static char *buff_file1 = "abc";
+static char *buff_file2 = "def";
 
-char *TCID = "stream01";
-int TST_TOTAL = 1;
-int local_flag;
+static void read_file(const char *file, const char *str, size_t n)
+{
+	char buf[n];
+	FILE *stream;
+	size_t len;
 
-#define PASSED 1
-#define FAILED 0
+	memset(buf, 0, sizeof(buf));
 
-/* XXX: add setup and cleanup. */
+	stream = SAFE_FOPEN(file, "r");
+	len = SAFE_FREAD(buf, n, n, stream);
+	SAFE_FCLOSE(stream);
 
-char progname[] = "stream01()";
-char tempfile1[40] = "";
-char tempfile2[40] = "";
+	TST_EXP_EXPR(len == n, "Read the entire %s file buffer", file);
+	TST_EXP_EQ_STRN(buf, str, len);
+}
 
-/*--------------------------------------------------------------------*/
-int main(int ac, char *av[])
+static void run(void)
 {
 	FILE *stream;
-	char buf[10];
-	int i;
-	int lc;
-
-	/*
-	 * parse standard options
-	 */
-	tst_parse_opts(ac, av, NULL, NULL);
 
-	local_flag = PASSED;
-	tst_tmpdir();
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
+	tst_res(TINFO, "Write %s file", FILENAME1);
+	stream = SAFE_FOPEN(FILENAME1, "a+");
+	SAFE_FWRITE(buff_file1, strlen(buff_file1), 3, stream);
 
-		sprintf(tempfile1, "stream011.%d", getpid());
-		sprintf(tempfile2, "stream012.%d", getpid());
-	/*--------------------------------------------------------------------*/
-		//block0:
-		if ((stream = fopen(tempfile1, "a+")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) a+ failed: %s",
-				 tempfile1,
-				 strerror(errno));
-		}
-		fwrite("a", 1, 1, stream);
-		if ((stream = freopen(tempfile2, "a+", stream)) == NULL) {
-			tst_brkm(TFAIL | TERRNO, NULL, "freopen(%s) a+ failed",
-				 tempfile2);
-		}
-		fwrite("a", 1, 1, stream);
-		fclose(stream);
+	tst_res(TINFO, "Write %s file streaming into %s file", FILENAME2, FILENAME1);
+	stream = SAFE_FREOPEN(FILENAME2, "a+", stream);
+	SAFE_FWRITE(buff_file2, strlen(buff_file2), 3, stream);
 
-		/* now check that a single "a" is in each file */
-		if ((stream = fopen(tempfile1, "r")) == NULL) {
-			tst_brkm(TFAIL | TERRNO, NULL, "fopen(%s) r failed",
-				 tempfile1);
-		} else {
-			for (i = 0; i < 10; i++)
-				buf[i] = 0;
-			fread(buf, 1, 1, stream);
-			if ((buf[0] != 'a') || (buf[1] != 0)) {
-				tst_resm(TFAIL, "bad contents in %s",
-					 tempfile1);
-				local_flag = FAILED;
-			}
-			fclose(stream);
-		}
-		if ((stream = fopen(tempfile2, "r")) == NULL) {
-			tst_brkm(TFAIL | TERRNO, NULL, "fopen(%s) r failed",
-				 tempfile2);
-		} else {
-			for (i = 0; i < 10; i++)
-				buf[i] = 0;
-			fread(buf, 1, 1, stream);
-			if ((buf[0] != 'a') || (buf[1] != 0)) {
-				tst_resm(TFAIL, "bad contents in %s",
-					 tempfile2);
-				local_flag = FAILED;
-			}
-			fclose(stream);
-		}
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed.");
-		} else {
-			tst_resm(TFAIL, "Test failed.");
-		}
+	SAFE_FCLOSE(stream);
 
-		local_flag = PASSED;
+	read_file(FILENAME1, buff_file1, 3);
+	read_file(FILENAME2, buff_file2, 3);
 
-	/*--------------------------------------------------------------------*/
-		unlink(tempfile1);
-		unlink(tempfile2);
-
-	}			/* end for */
-	tst_rmdir();
-	tst_exit();
+	SAFE_UNLINK(FILENAME1);
+	SAFE_UNLINK(FILENAME2);
 }
+
+static struct tst_test test = {
+	.test_all = run,
+	.needs_tmpdir = 1,
+};

-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH v2 3/6] fs: rewrite stream02 test using new API
  2026-03-04 13:25 [LTP] [PATCH v2 0/6] Rewrite fs stream testing suite Andrea Cervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 1/6] Add safe macros for " Andrea Cervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 2/6] fs: rewrite stream01 test using new API Andrea Cervesato
@ 2026-03-04 13:25 ` Andrea Cervesato
  2026-04-07 14:59   ` Cyril Hrubis
  2026-03-04 13:25 ` [LTP] [PATCH v2 4/6] fs: rewrite stream03 " Andrea Cervesato
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Andrea Cervesato @ 2026-03-04 13:25 UTC (permalink / raw)
  To: Linux Test Project

From: Andrea Cervesato <andrea.cervesato@suse.com>

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/fs/stream/stream02.c | 136 +++++++++-------------------------
 1 file changed, 33 insertions(+), 103 deletions(-)

diff --git a/testcases/kernel/fs/stream/stream02.c b/testcases/kernel/fs/stream/stream02.c
index 98473d86aab686eea2212c0e005a46e950f74ae8..c08bdbed0754453c6ab666fe5e733d31383587fb 100644
--- a/testcases/kernel/fs/stream/stream02.c
+++ b/testcases/kernel/fs/stream/stream02.c
@@ -1,119 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
+ * Copyright (c) International Business Machines  Corp., 2002
+ *	ported from SPIE section2/filesuite/stream2.c, by Airong Zhang
  *
- *   Copyright (c) International Business Machines  Corp., 2002
- *
- *   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 will 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, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
  */
-/* ported from SPIE section2/filesuite/stream2.c, by Airong Zhang */
-
-/*======================================================================
-	=================== TESTPLAN SEGMENT ===================
->KEYS:  < fseek() mknod() fopen()
->WHAT:  < 1)
->HOW:   < 1)
->BUGS:  <
-======================================================================*/
 
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "test.h"
-
-char *TCID = "stream02";
-int TST_TOTAL = 1;
-int local_flag;
+/*\
+ * Verify that it's possible to `fopen()` a file that has been created by
+ * `mknod()` using different modes.
+ */
 
-#define PASSED 1
-#define FAILED 0
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
 
-char progname[] = "stream02()";
-char tempfile1[40] = "";
+#define FILENAME "ltp_file_node"
 
-/* XXX: add cleanup + setup. */
+static const char *const modes[] = {
+	"r+",
+	"w+",
+	"a+",
+};
 
-/*--------------------------------------------------------------------*/
-int main(int ac, char *av[])
+static void run(void)
 {
 	FILE *stream;
-	int fd;
-	int lc;
-
-	/*
-	 * parse standard options
-	 */
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	local_flag = PASSED;
-	tst_tmpdir();
 
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
+	SAFE_MKNOD(FILENAME, (S_IFIFO | 0666), 0);
 
-		sprintf(tempfile1, "stream1.%d", getpid());
-	/*--------------------------------------------------------------------*/
-		//block0:
-		if (mknod(tempfile1, (S_IFIFO | 0666), 0) != 0) {
-			tst_resm(TFAIL, "mknod failed in block0: %s",
-				 strerror(errno));
-			local_flag = FAILED;
-			goto block1;
+	for (size_t i = 0; i < ARRAY_SIZE(modes); i++) {
+		stream = SAFE_FOPEN(FILENAME, modes[i]);
+		if (!stream) {
+			tst_res(TFAIL, "fopen(%s) returned NULL pointer", modes[i]);
+			return;
 		}
-		if ((stream = fopen(tempfile1, "w+")) == NULL) {
-			tst_resm(TFAIL, "fopen(%s) w+ failed for pipe file: %s",
-				 tempfile1, strerror(errno));
-			local_flag = FAILED;
-		} else {
-			fclose(stream);
-		}
-		if ((stream = fopen(tempfile1, "a+")) == NULL) {
-			tst_resm(TFAIL, "fopen(%s) a+ failed: %s", tempfile1,
-				 strerror(errno));
-			local_flag = FAILED;
-		} else {
-			fclose(stream);
-			unlink(tempfile1);
-		}
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed in block0.");
-		} else {
-			tst_resm(TFAIL, "Test failed in block0.");
-		}
-		local_flag = PASSED;
 
-	/*--------------------------------------------------------------------*/
-block1:
-		if ((fd = open("/dev/tty", O_WRONLY)) >= 0) {
-			close(fd);
-			if ((stream = fopen("/dev/tty", "w")) == NULL) {
-				tst_resm(TFAIL | TERRNO,
-					 "fopen(/dev/tty) write failed");
-				local_flag = FAILED;
-			} else {
-				fclose(stream);
-			}
-		}
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed in block1.");
-		} else {
-			tst_resm(TFAIL, "Test failed in block1.");
-		}
+		SAFE_FCLOSE(stream);
+
+		tst_res(TPASS, "Opened file using '%s' mode", modes[i]);
+	}
 
-	/*--------------------------------------------------------------------*/
-	}			/* end for */
-	tst_rmdir();
-	tst_exit();
+	SAFE_UNLINK(FILENAME);
 }
+
+static struct tst_test test = {
+	.test_all = run,
+	.needs_tmpdir = 1,
+};

-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH v2 4/6] fs: rewrite stream03 test using new API
  2026-03-04 13:25 [LTP] [PATCH v2 0/6] Rewrite fs stream testing suite Andrea Cervesato
                   ` (2 preceding siblings ...)
  2026-03-04 13:25 ` [LTP] [PATCH v2 3/6] fs: rewrite stream02 test using new API Andrea Cervesato
@ 2026-03-04 13:25 ` Andrea Cervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 5/6] fs: rewrite stream04 " Andrea Cervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 6/6] fs: rewrite stream05 " Andrea Cervesato
  5 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-03-04 13:25 UTC (permalink / raw)
  To: Linux Test Project

From: Andrea Cervesato <andrea.cervesato@suse.com>

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/fs/stream/stream03.c | 326 ++++++----------------------------
 1 file changed, 50 insertions(+), 276 deletions(-)

diff --git a/testcases/kernel/fs/stream/stream03.c b/testcases/kernel/fs/stream/stream03.c
index 31715f740a070d01aec1087981e092b361e656da..24928c5e1a15cc4a5b17b22bcfb907519ed9b4e4 100644
--- a/testcases/kernel/fs/stream/stream03.c
+++ b/testcases/kernel/fs/stream/stream03.c
@@ -1,297 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
+ * Copyright (c) International Business Machines  Corp., 2002
+ *	ported from SPIE, section2/filesuite/stream3.c, by Airong Zhang
  *
- *   Copyright (c) International Business Machines  Corp., 2002
- *
- *   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 will 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, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
  */
 
-/* ported from SPIE, section2/filesuite/stream3.c, by Airong Zhang */
-
-/*======================================================================
-	=================== TESTPLAN SEGMENT ===================
->KEYS:  < fseek() ftell()
->WHAT:  < 1) Ensure ftell reports the correct current byte offset.
->HOW:   < 1) Open a file, write to it, reposition the file pointer and
-	     check it.
->BUGS:  <
-======================================================================*/
-#define _XOPEN_SOURCE 500
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <inttypes.h>
-#include "test.h"
+/*\
+ * Verify that `ftell()` reports the correct current byte offset after
+ * moving it.
+ */
 
-char *TCID = "stream03";
-int TST_TOTAL = 1;
-int local_flag;
+#include "tst_test.h"
+#include "tst_rand_data.h"
+#include "tst_safe_stdio.h"
 
-#define PASSED 1
-#define FAILED 0
+#define FILENAME "ltp_file"
+#define DATASIZE 30
+#define BUFFSIZE 10
 
-char progname[] = "stream03()";
-char tempfile1[40] = "";
+static char *data;
+static char *buff;
 
-int main(int ac, char *av[])
+static void run(void)
 {
 	FILE *stream;
-	char buf[30];
-	char *junk = "abcdefghijklmnopqrstuvwxyz";
-	long pos;
-	off_t opos;
-	int lc;
-
-	/*
-	 * parse standard options
-	 */
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	local_flag = PASSED;
-	tst_tmpdir();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-
-		sprintf(tempfile1, "stream03.%d", getpid());
-	/*--------------------------------------------------------------------*/
-		//block0:
-
-		if ((stream = fopen(tempfile1, "a+")) == NULL) {
-			tst_brkm(TBROK, NULL, "fopen(%s) a+ failed: %s",
-				 tempfile1,
-				 strerror(errno));
-		}
-
-		/* make sure offset of zero at start */
-		pos = ftell(stream);
-
-		if (pos != 0) {
-			tst_resm(TFAIL, "file pointer descrepancy 1");
-			local_flag = FAILED;
-		}
-
-		/* write something and check */
-		if (fwrite(junk, sizeof(*junk), strlen(junk), stream) == 0) {
-			tst_brkm(TFAIL, NULL, "fwrite failed: %s",
-				 strerror(errno));
-		}
-
-		pos = ftell(stream);
-
-		if (pos != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk)=%zi: file pointer descrepancy 2 (pos=%li)",
-				 strlen(junk), pos);
-			local_flag = FAILED;
-		}
-
-		/* rewind and check */
-		rewind(stream);
-		pos = ftell(stream);
-
-		if (pos != 0) {
-			tst_resm(TFAIL,
-				 "file pointer descrepancy 3 (pos=%li, wanted pos=0)",
-				 pos);
-			local_flag = FAILED;
-		}
-
-		/* seek from current position and then check */
-		if (fseek(stream, strlen(junk), 1) != 0) {
-			tst_brkm(TFAIL, NULL, "fseek failed: %s",
-				 strerror(errno));
-		}
-
-		pos = ftell(stream);
-
-		if (pos != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk)=%zi: file pointer descrepancy 4 (pos=%li)",
-				 strlen(junk), pos);
-			local_flag = FAILED;
-		}
-
-		/* seek from end of file and then check */
-		if (fseek(stream, 0, 2) != 0) {
-			tst_brkm(TFAIL, NULL, "fseek failed: %s",
-				 strerror(errno));
-		}
-
-		pos = ftell(stream);
-
-		if (pos != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk)=%zi: file pointer descrepancy 5 (pos=%li)",
-				 strlen(junk), pos);
-			local_flag = FAILED;
-		}
-
-		/* rewind with seek and then check */
-		if (fseek(stream, 0, 0) != 0) {
-			tst_brkm(TFAIL, NULL, "fseek failed: %s",
-				 strerror(errno));
-		}
 
-		pos = ftell(stream);
+	memset(buff, 0, BUFFSIZE);
 
-		if (pos != 0) {
-			tst_resm(TFAIL,
-				 "file pointer descrepancy 6 (pos=%li, wanted pos=0)",
-				 pos);
-			local_flag = FAILED;
-		}
+	stream = SAFE_FOPEN(FILENAME, "a+");
+	TST_EXP_EQ_LI(SAFE_FTELL(stream), 0);
 
-		/* read till EOF, do getc and then check ftell */
-		while (fgets(buf, sizeof(buf), stream)) ;
-		pos = ftell(stream);
-		getc(stream);
-		pos = ftell(stream);
+	SAFE_FWRITE(data, 1, DATASIZE, stream);
+	TST_EXP_EQ_LI(SAFE_FTELL(stream), DATASIZE);
 
-		if (pos != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk)=%zi: file pointer descrepancy 7 (pos=%li)",
-				 strlen(junk), pos);
-			local_flag = FAILED;
-		}
+	rewind(stream);
+	TST_EXP_EQ_LI(SAFE_FTELL(stream), SEEK_SET);
 
-		fclose(stream);
+	SAFE_FSEEK(stream, 10, SEEK_CUR);
+	TST_EXP_EQ_LI(SAFE_FTELL(stream), 10);
 
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed in block0.");
-		} else {
-			tst_resm(TFAIL, "Test failed in block0.");
-		}
+	SAFE_FSEEK(stream, 0, SEEK_END);
+	TST_EXP_EQ_LI(SAFE_FTELL(stream), DATASIZE);
 
-		local_flag = PASSED;
+	SAFE_FSEEK(stream, 0, SEEK_SET);
+	TST_EXP_EQ_LI(SAFE_FTELL(stream), 0);
 
-		unlink(tempfile1);
-	/*--------------------------------------------------------------------*/
-		//block1:
-		if ((stream = fopen(tempfile1, "a+")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) a+ failed: %s",
-				 tempfile1,
-				 strerror(errno));
-		}
+	while (fgets(buff, BUFFSIZE, stream))
+		;
+	TST_EXP_EQ_LI(SAFE_FTELL(stream), DATASIZE);
 
-		/* make sure offset of zero at start */
-		opos = ftello(stream);
-
-		if (opos != 0) {
-			tst_resm(TFAIL,
-				 "file pointer descrepancy 1 (opos=%" PRId64
-				 ", wanted opos=0)", (int64_t) opos);
-			local_flag = FAILED;
-		}
-
-		/* write something and check */
-		if (fwrite(junk, sizeof(*junk), strlen(junk), stream) == 0) {
-			tst_brkm(TFAIL, NULL, "fwrite failed: %s",
-				 strerror(errno));
-		}
-
-		opos = ftello(stream);
-
-		if (opos != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk)=%zi: file pointer descrepancy 2 (opos=%"
-				 PRId64 ")", strlen(junk), (int64_t) opos);
-			local_flag = FAILED;
-		}
-
-		/* rewind and check */
-		rewind(stream);
-		opos = ftello(stream);
-
-		if (opos != 0) {
-			tst_resm(TFAIL,
-				 "file pointer descrepancy 3 (opos=%" PRId64
-				 ", wanted opos=0)", (int64_t) opos);
-			local_flag = FAILED;
-		}
-
-		/* seek from current position and then check */
-		if (fseeko(stream, strlen(junk), 1) != 0) {
-			tst_brkm(TFAIL, NULL, "fseeko failed: %s",
-				 strerror(errno));
-		}
-
-		opos = ftello(stream);
-
-		if (opos != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk)=%zi: file pointer descrepancy 4 (opos=%"
-				 PRId64 ")", strlen(junk), (int64_t) opos);
-			local_flag = FAILED;
-		}
-
-		/* seek from end of file and then check */
-		if (fseeko(stream, 0, 2) != 0) {
-			tst_brkm(TFAIL, NULL, "fseeko failed: %s",
-				 strerror(errno));
-		}
-
-		opos = ftello(stream);
-
-		if (opos != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk)=%zi: file pointer descrepancy 5 (opos=%"
-				 PRId64 ")", strlen(junk), (int64_t) opos);
-			local_flag = FAILED;
-		}
-
-		/* rewind with seek and then check */
-		if (fseeko(stream, 0, 0) != 0) {
-			tst_brkm(TFAIL, NULL, "fseeko failed: %s",
-				 strerror(errno));
-		}
-
-		opos = ftello(stream);
-
-		if (opos != 0) {
-			tst_resm(TFAIL,
-				 "file pointer descrepancy 6 (opos=%" PRId64
-				 ", wanted opos=0)", (int64_t) opos);
-			local_flag = FAILED;
-		}
-
-		/* read till EOF, do getc and then check ftello */
-		while (fgets(buf, sizeof(buf), stream)) ;
-
-		opos = ftello(stream);
-		getc(stream);
-		opos = ftello(stream);
-
-		if (opos != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk)=%zi: file pointer descrepancy 7 (opos=%li)",
-				 strlen(junk), opos);
-			local_flag = FAILED;
-		}
-
-		fclose(stream);
-
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed in block1.");
-		} else {
-			tst_resm(TFAIL, "Test failed in block1.");
-		}
-
-		unlink(tempfile1);
-	}
+	SAFE_FCLOSE(stream);
+	SAFE_UNLINK(FILENAME);
+}
 
-	tst_rmdir();
-	tst_exit();
+static void setup(void)
+{
+	memcpy(data, tst_rand_data, DATASIZE);
 }
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.needs_tmpdir = 1,
+	.bufs = (struct tst_buffers[]) {
+		{&data, .size = DATASIZE},
+		{&buff, .size = BUFFSIZE},
+		{},
+	},
+};

-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH v2 5/6] fs: rewrite stream04 test using new API
  2026-03-04 13:25 [LTP] [PATCH v2 0/6] Rewrite fs stream testing suite Andrea Cervesato
                   ` (3 preceding siblings ...)
  2026-03-04 13:25 ` [LTP] [PATCH v2 4/6] fs: rewrite stream03 " Andrea Cervesato
@ 2026-03-04 13:25 ` Andrea Cervesato
  2026-03-04 13:25 ` [LTP] [PATCH v2 6/6] fs: rewrite stream05 " Andrea Cervesato
  5 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-03-04 13:25 UTC (permalink / raw)
  To: Linux Test Project

From: Andrea Cervesato <andrea.cervesato@suse.com>

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/fs/stream/stream04.c | 147 +++++++++-------------------------
 1 file changed, 40 insertions(+), 107 deletions(-)

diff --git a/testcases/kernel/fs/stream/stream04.c b/testcases/kernel/fs/stream/stream04.c
index 3dc679151a6a81aab8c713605c258fae2c2b3adf..560792f062f3bbb0fcb9164ffd9095803fe6c4fe 100644
--- a/testcases/kernel/fs/stream/stream04.c
+++ b/testcases/kernel/fs/stream/stream04.c
@@ -1,124 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
+ * Copyright (c) International Business Machines  Corp., 2002
+ *	ported from SPIE, section2/filesuite/stream4.c, by Airong Zhang
  *
- *   Copyright (c) International Business Machines  Corp., 2002
- *
- *   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 will 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, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
  */
 
-/* Ported from SPIE, section2/iosuite/stream4.c, by Airong Zhang */
-
-/*======================================================================
-	=================== TESTPLAN SEGMENT ===================
->KEYS:  < fwrite() fread()
->WHAT:  < 1) Ensure fwrite appends data to stream.
-	< 2) Ensure fread and fwrite return values are valid.
->HOW:   < 1) Open a file, write to it, and then check it.
-	< 2) Fwrite a know quanity, check return value.
-	<    Fread a know quanity, check return value.
->BUGS:  <
-======================================================================*/
-
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "test.h"
-
-char *TCID = "stream04";
-int TST_TOTAL = 1;
-int local_flag;
+/*\
+ * Ensure that `fwrite()` is appending data to stream and `fread()`
+ * `fwrite()` are returning the right data.
+ */
 
-#define PASSED 1
-#define FAILED 0
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
 
-char progname[] = "stream04()";
-char tempfile1[40] = "";
-long ftell();
+#define FILENAME "ltp_file"
+#define DATA "abcdefghijklmnopqrstuvwxyz"
+#define DATASIZE sizeof(DATA)
 
-/* XXX: add setup and cleanup */
+static char *data;
+static char *buff;
 
-/*--------------------------------------------------------------------*/
-int main(int ac, char *av[])
+static void run(void)
 {
 	FILE *stream;
-	char *junk = "abcdefghijklmnopqrstuvwxyz";
-	char *inbuf;
-	int ret;
 
-	int lc;
+	memset(buff, 0, DATASIZE);
 
-	/*
-	 * parse standard options
-	 */
-	tst_parse_opts(ac, av, NULL, NULL);
-	tst_tmpdir();
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
+	stream = SAFE_FOPEN(FILENAME, "a+");
+	TST_EXP_EQ_LI(fwrite(data, 1, DATASIZE, stream), DATASIZE);
+	SAFE_FCLOSE(stream);
 
-		local_flag = PASSED;
+	stream = SAFE_FOPEN(FILENAME, "r+");
+	TST_EXP_EQ_LI(fread(buff, 1, DATASIZE, stream), DATASIZE);
+	SAFE_FCLOSE(stream);
 
-		sprintf(tempfile1, "stream04.%d", getpid());
-	/*--------------------------------------------------------------------*/
-		//block0:
-		if ((stream = fopen(tempfile1, "a+")) == NULL) {
-			tst_brkm(TFAIL | TERRNO, tst_rmdir, "fopen(%s) a+ failed",
-				 tempfile1);
-		}
-		/* write something and check */
-		if ((ret =
-		     fwrite(junk, sizeof(*junk), strlen(junk), stream)) == 0) {
-			tst_brkm(TFAIL, tst_rmdir, "fwrite failed: %s",
-				 strerror(errno));
-		}
+	SAFE_UNLINK(FILENAME);
 
-		if ((size_t) ret != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk) = %zi != return value from fwrite = %zi",
-				 strlen(junk), ret);
-			local_flag = FAILED;
-		}
+	TST_EXP_EQ_STRN(data, buff, DATASIZE);
+}
 
-		fclose(stream);
-		if ((stream = fopen(tempfile1, "r+")) == NULL) {
-			tst_brkm(TFAIL, tst_rmdir, "fopen(%s) r+ failed: %s", tempfile1,
-				 strerror(errno));
-		}
-		if ((inbuf = malloc(strlen(junk))) == 0) {
-			tst_brkm(TBROK, tst_rmdir, "test failed because of malloc: %s",
-				 strerror(errno));
-		}
-		if ((ret =
-		     fread(inbuf, sizeof(*junk), strlen(junk), stream)) == 0) {
-			tst_brkm(TFAIL, tst_rmdir, "fread failed: %s",
-				 strerror(errno));
-		}
-		if ((size_t) ret != strlen(junk)) {
-			tst_resm(TFAIL,
-				 "strlen(junk) = %zi != return value from fread = %zi",
-				 strlen(junk), ret);
-			local_flag = FAILED;
-		}
-		fclose(stream);
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed.");
-		} else {
-			tst_resm(TFAIL, "Test failed.");
-		}
-	/*--------------------------------------------------------------------*/
-		unlink(tempfile1);
-	}			/* end for */
-	tst_rmdir();
-	tst_exit();
+static void setup(void)
+{
+	memcpy(data, DATA, DATASIZE);
 }
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.needs_tmpdir = 1,
+	.bufs = (struct tst_buffers []) {
+		{&data, .size = DATASIZE},
+		{&buff, .size = DATASIZE},
+		{},
+	},
+};

-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH v2 6/6] fs: rewrite stream05 test using new API
  2026-03-04 13:25 [LTP] [PATCH v2 0/6] Rewrite fs stream testing suite Andrea Cervesato
                   ` (4 preceding siblings ...)
  2026-03-04 13:25 ` [LTP] [PATCH v2 5/6] fs: rewrite stream04 " Andrea Cervesato
@ 2026-03-04 13:25 ` Andrea Cervesato
  2026-04-07 15:30   ` Cyril Hrubis
  5 siblings, 1 reply; 11+ messages in thread
From: Andrea Cervesato @ 2026-03-04 13:25 UTC (permalink / raw)
  To: Linux Test Project

From: Andrea Cervesato <andrea.cervesato@suse.com>

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/fs/stream/stream05.c | 258 +++++++---------------------------
 1 file changed, 47 insertions(+), 211 deletions(-)

diff --git a/testcases/kernel/fs/stream/stream05.c b/testcases/kernel/fs/stream/stream05.c
index f561744c3da86cc5d80b97c9707f5583059d21f0..90989451bd45e32350946939a9f1acb7657be3a0 100644
--- a/testcases/kernel/fs/stream/stream05.c
+++ b/testcases/kernel/fs/stream/stream05.c
@@ -1,230 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
+ * Copyright (c) International Business Machines  Corp., 2002
+ *	ported from SPIE section2/filesuite/stream.c, by Airong Zhang
  *
- *   Copyright (c) International Business Machines  Corp., 2002
- *
- *   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 will 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, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
  */
 
-/* ported from SPIE, section2/filesuite/stream.c, by Airong Zhang */
-
-/*======================================================================
-	=================== TESTPLAN SEGMENT ===================
->KEYS:  < ferror() feof() clearerr() fileno()
->WHAT:  < 1) check that ferror returns zero
-	< 2) check fileno returns valid file descriptor
-	< 3) check that feof returns zero (nonzero) appropriately
-	< 4) check that clearerr resets EOF indicator.
->HOW:   < 1) open a stream and immediately execute ferror
-	< 2) use the file des returned from fileno to read a file
-	<    written with stream - compare actual vs expected.
-	< 3) open stream and ensure feof returns zero, read to end of
-	<    file and ensure feof returns non-zero.
-	< 4) after 3) above use clearerr and then use feof to ensure
-	<    clearerr worked
->BUGS:  <
-======================================================================*/
-
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include "test.h"
+/*\
+ * Verify that it's possible to read/write on a file descriptor returned by
+ * `fileno()` and to close it, leaving `fclose()` to raise EBADF error.
+ */
 
-char *TCID = "stream05";
-int TST_TOTAL = 1;
-int local_flag;
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
+#include "tst_rand_data.h"
 
-#define PASSED 1
-#define FAILED 0
+#define FILENAME "ltp_file"
+#define DATASIZE 3
+#define BUFFSIZE (2 * DATASIZE)
 
-char progname[] = "stream05()";
-char tempfile[40] = "";
+static char *data;
+static char *buff;
 
-/*--------------------------------------------------------------------*/
-int main(int ac, char *av[])
+static void run(void)
 {
+	int fd;
 	FILE *stream;
-	char buf[10];
-	int nr, fd;
-
-	int lc;
-
-	/*
-	 * parse standard options
-	 */
-	tst_parse_opts(ac, av, NULL, NULL);
-	tst_tmpdir();
-	local_flag = PASSED;
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		local_flag = PASSED;
-
-		sprintf(tempfile, "stream05.%d", getpid());
-	/*--------------------------------------------------------------------*/
-		//block0:
-		if ((stream = fopen(tempfile, "a+")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) a+ failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-		fprintf(stream, "a");
-		fclose(stream);
-
-		if ((stream = fopen(tempfile, "r+")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) r+ failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-
-		/* check that ferror returns zero */
-		if (ferror(stream) != 0) {
-			tst_resm(TFAIL, "ferror did not return zero: %s",
-				 strerror(errno));
-			local_flag = FAILED;
-		}
-
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed in block0.");
-		} else {
-			tst_resm(TFAIL, "Test failed in block0.");
-		}
 
-		local_flag = PASSED;
+	memset(buff, 0, BUFFSIZE);
 
-	/*--------------------------------------------------------------------*/
-		//block1:
+	stream = SAFE_FOPEN(FILENAME, "a+");
+	SAFE_FWRITE(data, 1, DATASIZE, stream);
+	SAFE_FFLUSH(stream);
 
-		/* check that fileno returns valid file descriptor */
-		fd = fileno(stream);
-		if ((nr = read(fd, buf, 1)) < 0) {
-			tst_brkm(TFAIL, NULL, "read failed: %s",
-				 strerror(errno));
-		}
-		if (nr != 1) {
-			tst_resm(TFAIL, "read did not read right number");
-			local_flag = FAILED;
-		}
-		if (buf[0] != 'a') {
-			tst_resm(TFAIL, "read returned bad values");
-			local_flag = FAILED;
-		}
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed in block1.");
-		} else {
-			tst_resm(TFAIL, "Test failed in block1.");
-		}
+	fd = SAFE_FILENO(stream);
+	SAFE_WRITE(SAFE_WRITE_ALL, fd, data, DATASIZE);
 
-		local_flag = PASSED;
-	/*--------------------------------------------------------------------*/
-		//block2:
+	fsync(fd);
+	SAFE_FSEEK(stream, 0, SEEK_SET);
+	SAFE_READ(1, fd, buff, BUFFSIZE);
 
-		/* read to EOF and ensure feof returns non-zero */
-		fclose(stream);
+	TST_EXP_EQ_STRN(data, buff, DATASIZE);
+	TST_EXP_EQ_STRN(data, buff + 3, DATASIZE);
 
-		if ((stream = fopen(tempfile, "r+")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) r+ failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-		if (feof(stream) != 0) {
-			tst_resm(TFAIL,
-				 "feof returned non-zero when it should not: %s",
-				 strerror(errno));
-			local_flag = FAILED;
-		}
-		fread(buf, 1, 2, stream);	/* read to EOF */
-		if (feof(stream) == 0) {
-			tst_resm(TFAIL,
-				 "feof returned zero when it should not: %s",
-				 strerror(errno));
-			local_flag = FAILED;
-		}
+	SAFE_CLOSE(fd);
+	TST_EXP_FAIL(fclose(stream), EBADF);
 
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed in block2.");
-		} else {
-			tst_resm(TFAIL, "Test failed in block2.");
-		}
-
-		local_flag = PASSED;
-	/*--------------------------------------------------------------------*/
-		//block3:
-		/* ensure clearerr works */
-		clearerr(stream);
-		if (feof(stream) != 0) {
-			tst_resm(TFAIL, "clearerr failed: %s", strerror(errno));
-			local_flag = FAILED;
-		}
-		if (local_flag == PASSED) {
-			tst_resm(TPASS, "Test passed in block3.");
-		} else {
-			tst_resm(TFAIL, "Test failed in block3.");
-		}
-
-		local_flag = PASSED;
-	/*--------------------------------------------------------------------*/
-		//block4:
-
-		/* test fopen "b" flags -- should be allowed but ignored */
-		(void)fclose(stream);
-
-		if ((stream = fopen(tempfile, "rb")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) rb failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-		(void)fclose(stream);
-
-		if ((stream = fopen(tempfile, "wb")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) wb failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-		(void)fclose(stream);
-
-		if ((stream = fopen(tempfile, "ab")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) ab failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-		(void)fclose(stream);
-
-		if ((stream = fopen(tempfile, "rb+")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) rb+ failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-		(void)fclose(stream);
-
-		if ((stream = fopen(tempfile, "wb+")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) wb+ failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-		(void)fclose(stream);
-
-		if ((stream = fopen(tempfile, "ab+")) == NULL) {
-			tst_brkm(TFAIL, NULL, "fopen(%s) ab+ failed: %s",
-				 tempfile,
-				 strerror(errno));
-		}
-		(void)fclose(stream);
+	SAFE_UNLINK(FILENAME);
+}
 
-		tst_resm(TPASS, "Test passed in block4.");
-	/*--------------------------------------------------------------------*/
-		unlink(tempfile);
-	}			/* end for */
-	tst_rmdir();
-	tst_exit();
+static void setup(void)
+{
+	memcpy(data, tst_rand_data, DATASIZE);
 }
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.needs_tmpdir = 1,
+	.bufs = (struct tst_buffers []) {
+		{&data, .size = DATASIZE},
+		{&buff, .size = BUFFSIZE},
+		{},
+	},
+};

-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH v2 2/6] fs: rewrite stream01 test using new API
  2026-03-04 13:25 ` [LTP] [PATCH v2 2/6] fs: rewrite stream01 test using new API Andrea Cervesato
@ 2026-04-07 14:57   ` Cyril Hrubis
  2026-04-10 15:00   ` [LTP] Add safe macros for stream testing suite acervesato
  1 sibling, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-07 14:57 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: Linux Test Project

Hi!
> +static void read_file(const char *file, const char *str, size_t n)
> +{
> +	char buf[n];
> +	FILE *stream;
> +	size_t len;
>  
> -#define PASSED 1
> -#define FAILED 0
> +	memset(buf, 0, sizeof(buf));
>  
> -/* XXX: add setup and cleanup. */
> +	stream = SAFE_FOPEN(file, "r");
> +	len = SAFE_FREAD(buf, n, n, stream);

Huh, we pass buffer of size n but ask it to read n * n bytes? That does
not seem to be right.

Also the buffer must always be bigger than n to allow the fread() to
read more bytes that we wrote, in a case that the file was written into
intcorrectly. So we need something like:

	char buf[128];

	...

	len = SAFE_FREAD(buf, 1, sizeof(buf), stream);

> +	SAFE_FCLOSE(stream);
>  
> -char progname[] = "stream01()";
> -char tempfile1[40] = "";
> -char tempfile2[40] = "";
> +	TST_EXP_EXPR(len == n, "Read the entire %s file buffer", file);
> +	TST_EXP_EQ_STRN(buf, str, len);
> +}
>  
> -/*--------------------------------------------------------------------*/
> -int main(int ac, char *av[])
> +static void run(void)
>  {
>  	FILE *stream;
> -	char buf[10];
> -	int i;
> -	int lc;
> -
> -	/*
> -	 * parse standard options
> -	 */
> -	tst_parse_opts(ac, av, NULL, NULL);
>  
> -	local_flag = PASSED;
> -	tst_tmpdir();
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> +	tst_res(TINFO, "Write %s file", FILENAME1);
> +	stream = SAFE_FOPEN(FILENAME1, "a+");
> +	SAFE_FWRITE(buff_file1, strlen(buff_file1), 3, stream);
>  
> -		sprintf(tempfile1, "stream011.%d", getpid());
> -		sprintf(tempfile2, "stream012.%d", getpid());
> -	/*--------------------------------------------------------------------*/
> -		//block0:
> -		if ((stream = fopen(tempfile1, "a+")) == NULL) {
> -			tst_brkm(TFAIL, NULL, "fopen(%s) a+ failed: %s",
> -				 tempfile1,
> -				 strerror(errno));
> -		}
> -		fwrite("a", 1, 1, stream);
> -		if ((stream = freopen(tempfile2, "a+", stream)) == NULL) {
> -			tst_brkm(TFAIL | TERRNO, NULL, "freopen(%s) a+ failed",
> -				 tempfile2);
> -		}
> -		fwrite("a", 1, 1, stream);
> -		fclose(stream);
> +	tst_res(TINFO, "Write %s file streaming into %s file", FILENAME2, FILENAME1);
> +	stream = SAFE_FREOPEN(FILENAME2, "a+", stream);
> +	SAFE_FWRITE(buff_file2, strlen(buff_file2), 3, stream);

And here as well we ask to write strlen(buff_fiel2) * 3
bytes but the buff_file2 is only 3 characters.

> +	SAFE_FCLOSE(stream);
>  
> -		local_flag = PASSED;
> +	read_file(FILENAME1, buff_file1, 3);
> +	read_file(FILENAME2, buff_file2, 3);
>  
> -	/*--------------------------------------------------------------------*/
> -		unlink(tempfile1);
> -		unlink(tempfile2);
> -
> -	}			/* end for */
> -	tst_rmdir();
> -	tst_exit();
> +	SAFE_UNLINK(FILENAME1);
> +	SAFE_UNLINK(FILENAME2);
>  }
> +
> +static struct tst_test test = {
> +	.test_all = run,
> +	.needs_tmpdir = 1,
> +};
> 
> -- 
> 2.51.0
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH v2 3/6] fs: rewrite stream02 test using new API
  2026-03-04 13:25 ` [LTP] [PATCH v2 3/6] fs: rewrite stream02 test using new API Andrea Cervesato
@ 2026-04-07 14:59   ` Cyril Hrubis
  0 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-07 14:59 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: Linux Test Project

Hi!
No change from v2?

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH v2 6/6] fs: rewrite stream05 test using new API
  2026-03-04 13:25 ` [LTP] [PATCH v2 6/6] fs: rewrite stream05 " Andrea Cervesato
@ 2026-04-07 15:30   ` Cyril Hrubis
  0 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-07 15:30 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: Linux Test Project

Hi!
> +	fsync(fd);

This should really be SAFE_FSYNC(fd);

> +	SAFE_FSEEK(stream, 0, SEEK_SET);
> +	SAFE_READ(1, fd, buff, BUFFSIZE);

Otherwise the rest looks fine.

With that fixed:

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [LTP] Add safe macros for stream testing suite
  2026-03-04 13:25 ` [LTP] [PATCH v2 2/6] fs: rewrite stream01 test using new API Andrea Cervesato
  2026-04-07 14:57   ` Cyril Hrubis
@ 2026-04-10 15:00   ` acervesato
  1 sibling, 0 replies; 11+ messages in thread
From: acervesato @ 2026-04-10 15:00 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: ltp

Hi Andrea,

our agent completed the review of the patch.

The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.

--- Reply to [PATCH 1/6] ---

On 2026-03-04, Andrea Cervesato wrote:
> Add safe macros for stream testing suite

> +size_t safe_fread(const char *file, const int lineno,
> +	void *ptr, size_t size, size_t n, FILE *stream)
> +{
> +	size_t ret;
> +
> +	ret = fread(ptr, size, n, stream);
> +	if (ret != n) {
> +		tst_brkm_(file, lineno, TBROK, NULL,
> +			"fread(%p, %lu, %lu, %p) read %lu bytes",
> +			ptr, size, n, stream, ret);

%lu is wrong for size_t on ILP32; use %zu. Also, ret is an item count,
not bytes — the message is misleading. Same issue in safe_fwrite.

Use TBROK | TERRNO here and in safe_fwrite; errno is set on actual I/O
errors, not just EOF.

> +FILE *safe_freopen(const char *file, const int lineno,
> +	       const char *path, const char *mode, FILE *stream)

Continuation-line alignment is inconsistent with the declaration in
safe_stdio_fn.h. Same applies to safe_fseek, safe_ftell. Align to the
opening parenthesis using tabs+spaces as in the header.

--- Reply to [PATCH 2/6] ---

On 2026-03-04, Andrea Cervesato wrote:
> fs: rewrite stream01 test using new API

Commit body is missing. Explain why the conversion is done (e.g. "Old
API is deprecated; convert to new tst_test.h-based API."). Same applies
to patches 3/6–6/6.

> +static void read_file(const char *file, const char *str, size_t n)
> +{
> +	char buf[n];
> +	...
> +	len = SAFE_FREAD(buf, n, n, stream);

fread(buf, n, n) attempts to read n*n bytes into a n-byte VLA — buffer
overflow. Change to SAFE_FREAD(buf, 1, n, stream).

> +	SAFE_FWRITE(buff_file1, strlen(buff_file1), 3, stream);

fwrite("abc", 3, 3) reads 9 bytes from a 3-byte literal — out-of-bounds
read. Change to SAFE_FWRITE(buff_file1, 1, strlen(buff_file1), stream).

--- Reply to [PATCH 3/6] ---

On 2026-03-04, Andrea Cervesato wrote:
> fs: rewrite stream02 test using new API

> +		stream = SAFE_FOPEN(FILENAME, modes[i]);
> +		if (!stream) {
> +			tst_res(TFAIL, "fopen(%s) returned NULL pointer", modes[i]);
> +			return;
> +		}

SAFE_FOPEN never returns NULL — it calls tst_brk(TBROK) on failure.
Remove the dead null check.

--- Reply to [PATCH 4/6] ---

On 2026-03-04, Andrea Cervesato wrote:
> fs: rewrite stream03 test using new API

> +	rewind(stream);
> +	TST_EXP_EQ_LI(SAFE_FTELL(stream), SEEK_SET);

SEEK_SET is a seek-direction constant (value 0), not a file position.
Use 0 as the expected value to avoid confusion.

Regards,
LTP AI Reviewer

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-04-10 15:03 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-04 13:25 [LTP] [PATCH v2 0/6] Rewrite fs stream testing suite Andrea Cervesato
2026-03-04 13:25 ` [LTP] [PATCH v2 1/6] Add safe macros for " Andrea Cervesato
2026-03-04 13:25 ` [LTP] [PATCH v2 2/6] fs: rewrite stream01 test using new API Andrea Cervesato
2026-04-07 14:57   ` Cyril Hrubis
2026-04-10 15:00   ` [LTP] Add safe macros for stream testing suite acervesato
2026-03-04 13:25 ` [LTP] [PATCH v2 3/6] fs: rewrite stream02 test using new API Andrea Cervesato
2026-04-07 14:59   ` Cyril Hrubis
2026-03-04 13:25 ` [LTP] [PATCH v2 4/6] fs: rewrite stream03 " Andrea Cervesato
2026-03-04 13:25 ` [LTP] [PATCH v2 5/6] fs: rewrite stream04 " Andrea Cervesato
2026-03-04 13:25 ` [LTP] [PATCH v2 6/6] fs: rewrite stream05 " Andrea Cervesato
2026-04-07 15:30   ` Cyril Hrubis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.