public inbox for ltp@lists.linux.it
 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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-03-04 13:25 ` [LTP] [PATCH v2 3/6] fs: rewrite stream02 " Andrea Cervesato
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 10+ 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] 10+ 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; 10+ 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] 10+ 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 " 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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
  0 siblings, 0 replies; 10+ 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] 10+ 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 " Andrea Cervesato
@ 2026-04-07 14:59   ` Cyril Hrubis
  0 siblings, 0 replies; 10+ 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] 10+ 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; 10+ 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] 10+ messages in thread

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

Thread overview: 10+ 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-03-04 13:25 ` [LTP] [PATCH v2 3/6] fs: rewrite stream02 " 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox