* [LTP] [PATCH 1/6] Add safe macros for stream testing suite
2026-01-23 16:18 [LTP] [PATCH 0/6] Rewrite fs stream testing suite Andrea Cervesato
@ 2026-01-23 16:18 ` Andrea Cervesato
2026-02-19 12:31 ` Cyril Hrubis
2026-01-23 16:18 ` [LTP] [PATCH 2/6] fs: rewrite stream01 test using new API Andrea Cervesato
` (4 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Andrea Cervesato @ 2026-01-23 16:18 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
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
include/safe_stdio_fn.h | 18 ++++++++++
include/tst_safe_stdio.h | 18 ++++++++++
lib/safe_stdio.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 123 insertions(+)
diff --git a/include/safe_stdio_fn.h b/include/safe_stdio_fn.h
index 3818a86571a6d9bc63fcf432c93683bb3298e5b2..79c08080fd16489ea5bd1606083ae900ba3b294f 100644
--- a/include/safe_stdio_fn.h
+++ b/include/safe_stdio_fn.h
@@ -32,4 +32,22 @@ 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 (cleanup_fn)(void),
+ void *ptr, size_t size, size_t n, FILE *stream);
+
+size_t safe_fwrite(const char *file, const int lineno, void (cleanup_fn)(void),
+ const void *ptr, size_t size, size_t n, FILE *stream);
+
+FILE *safe_freopen(const char *file, const int lineno, void (cleanup_fn)(void),
+ const char *path, const char *mode, FILE *stream);
+
+int safe_fseek(const char *file, const int lineno, void (cleanup_fn)(void),
+ FILE *f, long offset, int whence);
+
+long safe_ftell(const char *file, const int lineno, void (cleanup_fn)(void),
+ FILE *f);
+
+int safe_fileno(const char *file, const int lineno, void (cleanup_fn)(void),
+ FILE *stream);
+
#endif /* SAFE_STDIO_FN_H__ */
diff --git a/include/tst_safe_stdio.h b/include/tst_safe_stdio.h
index e4bff34da15c9116809fcf851cbf544a51e384ef..b757b7e36db69190df45b3af1f39058e24221379 100644
--- a/include/tst_safe_stdio.h
+++ b/include/tst_safe_stdio.h
@@ -21,4 +21,22 @@
#define SAFE_POPEN(command, type) \
safe_popen(__FILE__, __LINE__, NULL, command, type)
+#define SAFE_FREAD(ptr, size, n, stream) \
+ safe_fread(__FILE__, __LINE__, NULL, ptr, size, n, stream)
+
+#define SAFE_FWRITE(ptr, size, n, stream) \
+ safe_fwrite(__FILE__, __LINE__, NULL, ptr, size, n, stream)
+
+#define SAFE_FREOPEN(path, mode, stream) \
+ safe_freopen(__FILE__, __LINE__, NULL, path, mode, stream)
+
+#define SAFE_FSEEK(f, offset, whence) \
+ safe_fseek(__FILE__, __LINE__, NULL, f, offset, whence)
+
+#define SAFE_FTELL(f) \
+ safe_ftell(__FILE__, __LINE__, NULL, f)
+
+#define SAFE_FILENO(f) \
+ safe_fileno(__FILE__, __LINE__, NULL, f)
+
#endif /* TST_SAFE_STDIO_H__ */
diff --git a/lib/safe_stdio.c b/lib/safe_stdio.c
index ab23e43bb0835cdca5eaa015bc873fd23f9a8408..fc7b11781e5e6a45963d20ef4146aa82084cd6b8 100644
--- a/lib/safe_stdio.c
+++ b/lib/safe_stdio.c
@@ -99,3 +99,90 @@ 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 (cleanup_fn)(void),
+ 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, cleanup_fn,
+ "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, void (cleanup_fn)(void),
+ 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, cleanup_fn,
+ "fwrite(%p, %lu, %lu, %p) written %lu bytes",
+ ptr, size, n, stream, ret);
+ }
+
+ return ret;
+}
+
+FILE *safe_freopen(const char *file, const int lineno, void (cleanup_fn)(void),
+ const char *path, const char *mode, FILE *stream)
+{
+ FILE *f = freopen(path, mode, stream);
+
+ if (f == NULL) {
+ tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
+ "freopen(%s,%s,%p) failed", path, mode, stream);
+ }
+
+ return f;
+}
+
+int safe_fseek(const char *file, const int lineno, void (cleanup_fn)(void),
+ FILE *f, long offset, int whence)
+{
+ int ret;
+
+ errno = 0;
+ ret = fseek(f, offset, whence);
+
+ if (ret == -1) {
+ tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
+ "fseek(%p, %ld, %d)", f, offset, whence);
+ }
+
+ return ret;
+}
+
+long safe_ftell(const char *file, const int lineno, void (cleanup_fn)(void),
+ FILE *f)
+{
+ long ret;
+
+ errno = 0;
+ ret = ftell(f);
+
+ if (ret == -1)
+ tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn, "ftell(%p)", f);
+
+ return ret;
+}
+
+int safe_fileno(const char *file, const int lineno, void (cleanup_fn)(void),
+ FILE *f)
+{
+ int ret;
+
+ errno = 0;
+ ret = fileno(f);
+
+ if (ret == -1)
+ tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn, "fileno(%p)", f);
+
+ return ret;
+}
--
2.51.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [LTP] [PATCH 1/6] Add safe macros for stream testing suite
2026-01-23 16:18 ` [LTP] [PATCH 1/6] Add safe macros for " Andrea Cervesato
@ 2026-02-19 12:31 ` Cyril Hrubis
2026-03-04 9:49 ` Andrea Cervesato via ltp
2026-03-04 12:20 ` Andrea Cervesato via ltp
0 siblings, 2 replies; 18+ messages in thread
From: Cyril Hrubis @ 2026-02-19 12:31 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Hi!
> Introduce the following SAFE_* macros for stream file testing:
>
> - SAFE_FREAD
> - SAFE_FWRITE
> - SAFE_FREOPEN
> - SAFE_FSEEK
> - SAFE_FTELL
> - SAFE_FILENO
>
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> include/safe_stdio_fn.h | 18 ++++++++++
> include/tst_safe_stdio.h | 18 ++++++++++
> lib/safe_stdio.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 123 insertions(+)
>
> diff --git a/include/safe_stdio_fn.h b/include/safe_stdio_fn.h
> index 3818a86571a6d9bc63fcf432c93683bb3298e5b2..79c08080fd16489ea5bd1606083ae900ba3b294f 100644
> --- a/include/safe_stdio_fn.h
> +++ b/include/safe_stdio_fn.h
> @@ -32,4 +32,22 @@ 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 (cleanup_fn)(void),
> + void *ptr, size_t size, size_t n, FILE *stream);
> +
> +size_t safe_fwrite(const char *file, const int lineno, void (cleanup_fn)(void),
> + const void *ptr, size_t size, size_t n, FILE *stream);
> +
> +FILE *safe_freopen(const char *file, const int lineno, void (cleanup_fn)(void),
> + const char *path, const char *mode, FILE *stream);
> +
> +int safe_fseek(const char *file, const int lineno, void (cleanup_fn)(void),
> + FILE *f, long offset, int whence);
> +
> +long safe_ftell(const char *file, const int lineno, void (cleanup_fn)(void),
> + FILE *f);
> +
> +int safe_fileno(const char *file, const int lineno, void (cleanup_fn)(void),
> + FILE *stream);
Newly added safe macros shouldn't add the cleanup_fn parameter, that is
kept only in the legacy macros that are stil used in the old library
tests.
Otherwise: 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] 18+ messages in thread
* Re: [LTP] [PATCH 1/6] Add safe macros for stream testing suite
2026-02-19 12:31 ` Cyril Hrubis
@ 2026-03-04 9:49 ` Andrea Cervesato via ltp
2026-03-04 10:06 ` Cyril Hrubis
2026-03-04 12:20 ` Andrea Cervesato via ltp
1 sibling, 1 reply; 18+ messages in thread
From: Andrea Cervesato via ltp @ 2026-03-04 9:49 UTC (permalink / raw)
To: Cyril Hrubis, Andrea Cervesato; +Cc: Linux Test Project
Hi!
>
> Newly added safe macros shouldn't add the cleanup_fn parameter, that is
> kept only in the legacy macros that are stil used in the old library
> tests.
The problem is that I don't know how to approach it, since the header is
correct, but we also have tso_safe_stdio.h and there's a mix of old
implementations/new implementations mixing together into tst_kernel.c.
I'm a bit puzzled. The point would be to move evrything in the new API,
including the core library.
--
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] 18+ messages in thread
* Re: [LTP] [PATCH 1/6] Add safe macros for stream testing suite
2026-03-04 9:49 ` Andrea Cervesato via ltp
@ 2026-03-04 10:06 ` Cyril Hrubis
2026-03-04 10:11 ` Andrea Cervesato via ltp
0 siblings, 1 reply; 18+ messages in thread
From: Cyril Hrubis @ 2026-03-04 10:06 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Hi!
> > Newly added safe macros shouldn't add the cleanup_fn parameter, that is
> > kept only in the legacy macros that are stil used in the old library
> > tests.
>
> The problem is that I don't know how to approach it, since the header is
> correct, but we also have tso_safe_stdio.h and there's a mix of old
> implementations/new implementations mixing together into tst_kernel.c.
Just do not add the cleanup_fn parameter to the new functions 1added
there. That's all I ask for here.
> I'm a bit puzzled. The point would be to move evrything in the new API,
> including the core library.
Well we can't until there are old tests using the old library left.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [LTP] [PATCH 1/6] Add safe macros for stream testing suite
2026-02-19 12:31 ` Cyril Hrubis
2026-03-04 9:49 ` Andrea Cervesato via ltp
@ 2026-03-04 12:20 ` Andrea Cervesato via ltp
1 sibling, 0 replies; 18+ messages in thread
From: Andrea Cervesato via ltp @ 2026-03-04 12:20 UTC (permalink / raw)
To: Cyril Hrubis, Andrea Cervesato; +Cc: Linux Test Project
>
> Otherwise: Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Just one thing about the tag: be aware that `b4 trailers -u -S` command
that updates all tags trailers inside commit messages will use
`Otherwise:` as a tag (lol).
The best way is to keep trailers in a new line.
--
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] 18+ messages in thread
* [LTP] [PATCH 2/6] fs: rewrite stream01 test using new API
2026-01-23 16:18 [LTP] [PATCH 0/6] Rewrite fs stream testing suite Andrea Cervesato
2026-01-23 16:18 ` [LTP] [PATCH 1/6] Add safe macros for " Andrea Cervesato
@ 2026-01-23 16:18 ` Andrea Cervesato
2026-02-19 13:05 ` Cyril Hrubis
2026-01-23 16:18 ` [LTP] [PATCH 3/6] fs: rewrite stream02 " Andrea Cervesato
` (3 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Andrea Cervesato @ 2026-01-23 16:18 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 | 153 ++++++++++------------------------
1 file changed, 46 insertions(+), 107 deletions(-)
diff --git a/testcases/kernel/fs/stream/stream01.c b/testcases/kernel/fs/stream/stream01.c
index af56bca3b916c080328c3356681efbd869b961d2..6d111dc36dcfbab8e0ba8d66d3e901ef36a71400 100644
--- a/testcases/kernel/fs/stream/stream01.c
+++ b/testcases/kernel/fs/stream/stream01.c
@@ -1,127 +1,66 @@
+// 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"
-
-char *TCID = "stream01";
-int TST_TOTAL = 1;
-int local_flag;
+static void read_file(const char *file)
+{
+ char buf[2];
+ FILE *stream;
-#define PASSED 1
-#define FAILED 0
+ memset(buf, 0, sizeof(buf));
-/* XXX: add setup and cleanup. */
+ stream = SAFE_FOPEN(file, "r");
+ SAFE_FREAD(buf, 1, 1, stream);
+ SAFE_FCLOSE(stream);
-char progname[] = "stream01()";
-char tempfile1[40] = "";
-char tempfile2[40] = "";
+ TST_EXP_EXPR((buf[0] == 'a') && (buf[1] == 0),
+ "%s file contains the correct data", file);
+}
-/*--------------------------------------------------------------------*/
-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("a", 1, 1, 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("a", 1, 1, 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);
+ read_file(FILENAME2);
- /*--------------------------------------------------------------------*/
- 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] 18+ messages in thread* Re: [LTP] [PATCH 2/6] fs: rewrite stream01 test using new API
2026-01-23 16:18 ` [LTP] [PATCH 2/6] fs: rewrite stream01 test using new API Andrea Cervesato
@ 2026-02-19 13:05 ` Cyril Hrubis
0 siblings, 0 replies; 18+ messages in thread
From: Cyril Hrubis @ 2026-02-19 13:05 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Hi!
> -char *TCID = "stream01";
> -int TST_TOTAL = 1;
> -int local_flag;
> +static void read_file(const char *file)
> +{
> + char buf[2];
> + FILE *stream;
>
> -#define PASSED 1
> -#define FAILED 0
> + memset(buf, 0, sizeof(buf));
>
> -/* XXX: add setup and cleanup. */
> + stream = SAFE_FOPEN(file, "r");
> + SAFE_FREAD(buf, 1, 1, stream);
Here we read at most 1 character from the stream.
> + SAFE_FCLOSE(stream);
>
> -char progname[] = "stream01()";
> -char tempfile1[40] = "";
> -char tempfile2[40] = "";
> + TST_EXP_EXPR((buf[0] == 'a') && (buf[1] == 0),
^
Hence this is always true
> + "%s file contains the correct data", file);
If we wanted to assert that the file has a single characted written into
it we need to let the fread() read the whole buffer:
SAFE_FREAD(buf, 2, 1, stream);
With that there is at least chance that the buf[1] may be overwritten
with some data.
Or we can check the size returned from fread(), if it was 1 there was a
single characted in the file. But again, we have to pass buffer that is
at least 2 bytes long.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 18+ messages in thread
* [LTP] [PATCH 3/6] fs: rewrite stream02 test using new API
2026-01-23 16:18 [LTP] [PATCH 0/6] Rewrite fs stream testing suite Andrea Cervesato
2026-01-23 16:18 ` [LTP] [PATCH 1/6] Add safe macros for " Andrea Cervesato
2026-01-23 16:18 ` [LTP] [PATCH 2/6] fs: rewrite stream01 test using new API Andrea Cervesato
@ 2026-01-23 16:18 ` Andrea Cervesato
2026-03-02 12:01 ` Cyril Hrubis
2026-01-23 16:18 ` [LTP] [PATCH 4/6] fs: rewrite stream03 " Andrea Cervesato
` (2 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Andrea Cervesato @ 2026-01-23 16:18 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 | 133 ++++++++--------------------------
1 file changed, 29 insertions(+), 104 deletions(-)
diff --git a/testcases/kernel/fs/stream/stream02.c b/testcases/kernel/fs/stream/stream02.c
index 98473d86aab686eea2212c0e005a46e950f74ae8..0c6f3737dda69623e5e2bdf35ee427de0ad24586 100644
--- a/testcases/kernel/fs/stream/stream02.c
+++ b/testcases/kernel/fs/stream/stream02.c
@@ -1,119 +1,44 @@
+// 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++) {
+ stream = SAFE_FOPEN(FILENAME, modes[i]);
+ SAFE_FCLOSE(stream);
- 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;
+ tst_res(TPASS, "Opened file using '%s' mode", modes[i]);
+ }
- /*--------------------------------------------------------------------*/
-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] 18+ messages in thread* [LTP] [PATCH 4/6] fs: rewrite stream03 test using new API
2026-01-23 16:18 [LTP] [PATCH 0/6] Rewrite fs stream testing suite Andrea Cervesato
` (2 preceding siblings ...)
2026-01-23 16:18 ` [LTP] [PATCH 3/6] fs: rewrite stream02 " Andrea Cervesato
@ 2026-01-23 16:18 ` Andrea Cervesato
2026-03-02 13:02 ` Cyril Hrubis
2026-01-23 16:18 ` [LTP] [PATCH 5/6] fs: rewrite stream04 " Andrea Cervesato
2026-01-23 16:18 ` [LTP] [PATCH 6/6] fs: rewrite stream05 " Andrea Cervesato
5 siblings, 1 reply; 18+ messages in thread
From: Andrea Cervesato @ 2026-01-23 16:18 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/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] 18+ messages in thread* [LTP] [PATCH 5/6] fs: rewrite stream04 test using new API
2026-01-23 16:18 [LTP] [PATCH 0/6] Rewrite fs stream testing suite Andrea Cervesato
` (3 preceding siblings ...)
2026-01-23 16:18 ` [LTP] [PATCH 4/6] fs: rewrite stream03 " Andrea Cervesato
@ 2026-01-23 16:18 ` Andrea Cervesato
2026-03-02 13:14 ` Cyril Hrubis
2026-01-23 16:18 ` [LTP] [PATCH 6/6] fs: rewrite stream05 " Andrea Cervesato
5 siblings, 1 reply; 18+ messages in thread
From: Andrea Cervesato @ 2026-01-23 16:18 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/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] 18+ messages in thread* [LTP] [PATCH 6/6] fs: rewrite stream05 test using new API
2026-01-23 16:18 [LTP] [PATCH 0/6] Rewrite fs stream testing suite Andrea Cervesato
` (4 preceding siblings ...)
2026-01-23 16:18 ` [LTP] [PATCH 5/6] fs: rewrite stream04 " Andrea Cervesato
@ 2026-01-23 16:18 ` Andrea Cervesato
2026-03-02 13:52 ` Cyril Hrubis
5 siblings, 1 reply; 18+ messages in thread
From: Andrea Cervesato @ 2026-01-23 16:18 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 | 256 ++++++----------------------------
1 file changed, 44 insertions(+), 212 deletions(-)
diff --git a/testcases/kernel/fs/stream/stream05.c b/testcases/kernel/fs/stream/stream05.c
index f561744c3da86cc5d80b97c9707f5583059d21f0..33262e9afac895e0727581e6c66e3dde7658e427 100644
--- a/testcases/kernel/fs/stream/stream05.c
+++ b/testcases/kernel/fs/stream/stream05.c
@@ -1,230 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * 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;
- /*--------------------------------------------------------------------*/
- //block1:
+ memset(buff, 0, BUFFSIZE);
- /* 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.");
- }
+ stream = SAFE_FOPEN(FILENAME, "a+");
+ SAFE_FWRITE(data, 1, DATASIZE, stream);
- local_flag = PASSED;
- /*--------------------------------------------------------------------*/
- //block2:
+ fd = TST_EXP_FD(SAFE_FILENO(stream));
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, data, DATASIZE);
- /* read to EOF and ensure feof returns non-zero */
- fclose(stream);
+ fsync(fd);
+ SAFE_FSEEK(stream, 0, SEEK_SET);
+ SAFE_READ(1, fd, buff, BUFFSIZE);
- 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;
- }
+ TST_EXP_EQ_STRN(data, buff, DATASIZE);
+ TST_EXP_EQ_STRN(data, buff + 3, DATASIZE);
- if (local_flag == PASSED) {
- tst_resm(TPASS, "Test passed in block2.");
- } else {
- tst_resm(TFAIL, "Test failed in block2.");
- }
+ SAFE_CLOSE(fd);
+ TST_EXP_FAIL(fclose(stream), EBADF);
- 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] 18+ messages in thread* Re: [LTP] [PATCH 6/6] fs: rewrite stream05 test using new API
2026-01-23 16:18 ` [LTP] [PATCH 6/6] fs: rewrite stream05 " Andrea Cervesato
@ 2026-03-02 13:52 ` Cyril Hrubis
0 siblings, 0 replies; 18+ messages in thread
From: Cyril Hrubis @ 2026-03-02 13:52 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Hi!
> +// SPDX-License-Identifier: GPL-2.0-or-later
> /*
> - *
> - * Copyright (c) International Business Machines Corp., 2002
Shouldn't this copyright stay?
> - * 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>
> */
>
...
> + stream = SAFE_FOPEN(FILENAME, "a+");
> + SAFE_FWRITE(data, 1, DATASIZE, stream);
Shouldn't this be SAFE_FFLUSH(stream) here?
The previous test closed and opened the stream before, which explicitly
flushed the buffers.
> - local_flag = PASSED;
> - /*--------------------------------------------------------------------*/
> - //block2:
> + fd = TST_EXP_FD(SAFE_FILENO(stream));
This is wrong, either we use SAFE_MACRO or TST_EXP macro. Using both of
them like this does not make any sense since the SAFE_FILENO() does not
return on a failure.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 18+ messages in thread