* [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite
@ 2026-04-16 14:33 Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 1/7] lib: add safe macros for " Andrea Cervesato
` (7 more replies)
0 siblings, 8 replies; 13+ messages in thread
From: Andrea Cervesato @ 2026-04-16 14:33 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 v3:
- fix stream01 buffer size
- add TST_EXP_PASS_PTR_NULL() macro
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 (7):
lib: add safe macros for stream testing suite
fs: rewrite stream01 test using new API
lib: add TST_EXP_PASS_PTR_NULL() macro
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 +++
include/tst_test_macros.h | 15 +-
lib/safe_stdio.c | 101 +++++++++++
testcases/kernel/fs/stream/stream01.c | 155 +++++-----------
testcases/kernel/fs/stream/stream02.c | 134 ++++----------
testcases/kernel/fs/stream/stream03.c | 326 ++++++----------------------------
testcases/kernel/fs/stream/stream04.c | 147 +++++----------
testcases/kernel/fs/stream/stream05.c | 258 +++++----------------------
9 files changed, 373 insertions(+), 805 deletions(-)
---
base-commit: 620d596c79493af089ba6a1c4dc79efcc76a67c7
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] 13+ messages in thread
* [LTP] [PATCH v2 1/7] lib: add safe macros for stream testing suite
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
@ 2026-04-16 14:33 ` Andrea Cervesato
2026-04-16 15:34 ` [LTP] " linuxtestproject.agent
2026-04-16 14:33 ` [LTP] [PATCH v2 2/7] fs: rewrite stream01 test using new API Andrea Cervesato
` (6 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Andrea Cervesato @ 2026-04-16 14:33 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] 13+ messages in thread
* [LTP] [PATCH v2 2/7] fs: rewrite stream01 test using new API
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 1/7] lib: add safe macros for " Andrea Cervesato
@ 2026-04-16 14:33 ` Andrea Cervesato
2026-04-16 15:26 ` Cyril Hrubis
2026-04-16 14:33 ` [LTP] [PATCH v2 3/7] lib: add TST_EXP_PASS_PTR_NULL() macro Andrea Cervesato
` (5 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Andrea Cervesato @ 2026-04-16 14:33 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Old LTP API is deprecated. Convert stream01 to new tst_test.h-based
API, using SAFE_FOPEN/SAFE_FWRITE/SAFE_FREOPEN/SAFE_FCLOSE macros
and structured result reporting.
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..ec4bf96a47a0fc291a4c9c9c13f46705d878ca91 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[128];
+ 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, 1, 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, n);
+}
-/*--------------------------------------------------------------------*/
-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, 1, strlen(buff_file1), 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, 1, strlen(buff_file2), 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] 13+ messages in thread
* [LTP] [PATCH v2 3/7] lib: add TST_EXP_PASS_PTR_NULL() macro
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 1/7] lib: add safe macros for " Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 2/7] fs: rewrite stream01 test using new API Andrea Cervesato
@ 2026-04-16 14:33 ` Andrea Cervesato
2026-04-16 15:15 ` Cyril Hrubis
2026-04-16 14:33 ` [LTP] [PATCH v2 4/7] fs: rewrite stream02 test using new API Andrea Cervesato
` (4 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Andrea Cervesato @ 2026-04-16 14:33 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add a variant of TST_EXP_PASS_PTR_VOID() that checks the return
value against NULL instead of (void *)-1. This is useful for libc
functions such as fopen() that return NULL on failure, allowing
tests to report TFAIL instead of TBROK when the call fails.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
include/tst_test_macros.h | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/include/tst_test_macros.h b/include/tst_test_macros.h
index 3d2287753b0419c82b1a878e8779def99d4bb4ca..2cfbdb5869af5c871e7086236a17b3a76e34b5d3 100644
--- a/include/tst_test_macros.h
+++ b/include/tst_test_macros.h
@@ -370,7 +370,20 @@ extern int TST_PASS;
* is converted to a string and used instead.
*/
#define TST_EXP_PASS_PTR_VOID(SCALL, ...) \
- TST_EXP_PASS_PTR_(SCALL, #SCALL, (void *)-1, ##__VA_ARGS__);
+ TST_EXP_PASS_PTR_(SCALL, #SCALL, (void *)-1, ##__VA_ARGS__);
+
+/**
+ * TST_EXP_PASS_PTR_NULL() - Test call to return a non-NULL pointer.
+ *
+ * @SCALL: Tested call.
+ * @...: A printf-like parameters.
+ *
+ * This macro works like TST_EXP_PASS_PTR_VOID() but checks the return
+ * value against NULL instead of (void *)-1. Use this for libc functions
+ * such as fopen() that return NULL on failure.
+ */
+#define TST_EXP_PASS_PTR_NULL(SCALL, ...) \
+ TST_EXP_PASS_PTR_(SCALL, #SCALL, NULL, ##__VA_ARGS__)
/*
* Returns true if err is in the exp_err array.
--
2.51.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [LTP] [PATCH v2 4/7] fs: rewrite stream02 test using new API
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
` (2 preceding siblings ...)
2026-04-16 14:33 ` [LTP] [PATCH v2 3/7] lib: add TST_EXP_PASS_PTR_NULL() macro Andrea Cervesato
@ 2026-04-16 14:33 ` Andrea Cervesato
2026-04-16 15:32 ` Cyril Hrubis
2026-04-16 14:33 ` [LTP] [PATCH v2 5/7] fs: rewrite stream03 " Andrea Cervesato
` (3 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Andrea Cervesato @ 2026-04-16 14:33 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Old LTP API is deprecated. Convert stream02 to new tst_test.h-based
API. Use TST_EXP_PASS_PTR_NULL() for fopen() calls so that a failure
reports TFAIL instead of TBROK.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/fs/stream/stream02.c | 134 ++++++++--------------------------
1 file changed, 30 insertions(+), 104 deletions(-)
diff --git a/testcases/kernel/fs/stream/stream02.c b/testcases/kernel/fs/stream/stream02.c
index 98473d86aab686eea2212c0e005a46e950f74ae8..9486ce85ac2472803ed873e0d626ac1fd759c674 100644
--- a/testcases/kernel/fs/stream/stream02.c
+++ b/testcases/kernel/fs/stream/stream02.c
@@ -1,119 +1,45 @@
+// 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();
+ SAFE_MKNOD(FILENAME, (S_IFIFO | 0666), 0);
- for (lc = 0; TEST_LOOPING(lc); lc++) {
+ for (size_t i = 0; i < ARRAY_SIZE(modes); i++) {
+ TST_EXP_PASS_PTR_NULL(fopen(FILENAME, modes[i]),
+ "fopen(%s, %s)", FILENAME, modes[i]);
- 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;
- }
- 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;
+ if (TST_PASS)
+ SAFE_FCLOSE(TST_RET_PTR);
+ }
- /*--------------------------------------------------------------------*/
-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.");
- }
-
- /*--------------------------------------------------------------------*/
- } /* 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] 13+ messages in thread
* [LTP] [PATCH v2 5/7] fs: rewrite stream03 test using new API
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
` (3 preceding siblings ...)
2026-04-16 14:33 ` [LTP] [PATCH v2 4/7] fs: rewrite stream02 test using new API Andrea Cervesato
@ 2026-04-16 14:33 ` Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 6/7] fs: rewrite stream04 " Andrea Cervesato
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Andrea Cervesato @ 2026-04-16 14:33 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Old LTP API is deprecated. Convert stream03 to new tst_test.h-based
API, verifying that ftell() reports correct byte offsets after
rewind, fseek and fgets operations.
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] 13+ messages in thread
* [LTP] [PATCH v2 6/7] fs: rewrite stream04 test using new API
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
` (4 preceding siblings ...)
2026-04-16 14:33 ` [LTP] [PATCH v2 5/7] fs: rewrite stream03 " Andrea Cervesato
@ 2026-04-16 14:33 ` Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 7/7] fs: rewrite stream05 " Andrea Cervesato
2026-04-16 18:21 ` [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato via ltp
7 siblings, 0 replies; 13+ messages in thread
From: Andrea Cervesato @ 2026-04-16 14:33 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Old LTP API is deprecated. Convert stream04 to new tst_test.h-based
API, verifying that fwrite() appends data and fread() returns the
correct content.
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] 13+ messages in thread
* [LTP] [PATCH v2 7/7] fs: rewrite stream05 test using new API
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
` (5 preceding siblings ...)
2026-04-16 14:33 ` [LTP] [PATCH v2 6/7] fs: rewrite stream04 " Andrea Cervesato
@ 2026-04-16 14:33 ` Andrea Cervesato
2026-04-16 18:21 ` [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato via ltp
7 siblings, 0 replies; 13+ messages in thread
From: Andrea Cervesato @ 2026-04-16 14:33 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Old LTP API is deprecated. Replace the old stream05 with a new test
that verifies read/write on a file descriptor obtained via fileno()
and that fclose() fails with EBADF after the fd is closed directly.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
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..04cb237a145246f607f874c97bc1758724b325a2 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:
+ SAFE_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] 13+ messages in thread
* Re: [LTP] [PATCH v2 3/7] lib: add TST_EXP_PASS_PTR_NULL() macro
2026-04-16 14:33 ` [LTP] [PATCH v2 3/7] lib: add TST_EXP_PASS_PTR_NULL() macro Andrea Cervesato
@ 2026-04-16 15:15 ` Cyril Hrubis
0 siblings, 0 replies; 13+ messages in thread
From: Cyril Hrubis @ 2026-04-16 15:15 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Hi!
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] 13+ messages in thread
* Re: [LTP] [PATCH v2 2/7] fs: rewrite stream01 test using new API
2026-04-16 14:33 ` [LTP] [PATCH v2 2/7] fs: rewrite stream01 test using new API Andrea Cervesato
@ 2026-04-16 15:26 ` Cyril Hrubis
0 siblings, 0 replies; 13+ messages in thread
From: Cyril Hrubis @ 2026-04-16 15:26 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Hi!
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] 13+ messages in thread
* Re: [LTP] [PATCH v2 4/7] fs: rewrite stream02 test using new API
2026-04-16 14:33 ` [LTP] [PATCH v2 4/7] fs: rewrite stream02 test using new API Andrea Cervesato
@ 2026-04-16 15:32 ` Cyril Hrubis
0 siblings, 0 replies; 13+ messages in thread
From: Cyril Hrubis @ 2026-04-16 15:32 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Hi!
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] 13+ messages in thread
* Re: [LTP] lib: add safe macros for stream testing suite
2026-04-16 14:33 ` [LTP] [PATCH v2 1/7] lib: add safe macros for " Andrea Cervesato
@ 2026-04-16 15:34 ` linuxtestproject.agent
0 siblings, 0 replies; 13+ messages in thread
From: linuxtestproject.agent @ 2026-04-16 15:34 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea,
--- [PATCH 3/7] ---
On Thu, 16 Apr 2026 16:33:37 +0200, Andrea Cervesato wrote:
> lib: add TST_EXP_PASS_PTR_NULL() macro
This lib commit is sandwiched between stream01 and stream02 test commits.
All library helper additions should come before the test rewrites that
depend on them.
--- [PATCH 5/7] ---
On Thu, 16 Apr 2026 16:33:39 +0200, 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 whence-direction constant (== 0), not a byte offset.
Use 0 here instead.
---
Note:
Our agent completed the review of the patch. The full review can be
found at: https://patchwork.ozlabs.org/project/ltp/list/?series=500172
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.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
` (6 preceding siblings ...)
2026-04-16 14:33 ` [LTP] [PATCH v2 7/7] fs: rewrite stream05 " Andrea Cervesato
@ 2026-04-16 18:21 ` Andrea Cervesato via ltp
7 siblings, 0 replies; 13+ messages in thread
From: Andrea Cervesato via ltp @ 2026-04-16 18:21 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Merged, thanks.
--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-04-16 18:21 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-16 14:33 [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 1/7] lib: add safe macros for " Andrea Cervesato
2026-04-16 15:34 ` [LTP] " linuxtestproject.agent
2026-04-16 14:33 ` [LTP] [PATCH v2 2/7] fs: rewrite stream01 test using new API Andrea Cervesato
2026-04-16 15:26 ` Cyril Hrubis
2026-04-16 14:33 ` [LTP] [PATCH v2 3/7] lib: add TST_EXP_PASS_PTR_NULL() macro Andrea Cervesato
2026-04-16 15:15 ` Cyril Hrubis
2026-04-16 14:33 ` [LTP] [PATCH v2 4/7] fs: rewrite stream02 test using new API Andrea Cervesato
2026-04-16 15:32 ` Cyril Hrubis
2026-04-16 14:33 ` [LTP] [PATCH v2 5/7] fs: rewrite stream03 " Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 6/7] fs: rewrite stream04 " Andrea Cervesato
2026-04-16 14:33 ` [LTP] [PATCH v2 7/7] fs: rewrite stream05 " Andrea Cervesato
2026-04-16 18:21 ` [LTP] [PATCH v2 0/7] Rewrite fs stream testing suite Andrea Cervesato via ltp
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox