tools/include/nolibc/stdio.h | 54 +++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-)
Using nolibc on nommu 68000, something I'm trying to build[0] wanted fread() and fseek() so I added them, they seem to work so I'm sharing them. Not sure if I need to add tests or something? Maybe there is a reason these weren't implemented in the first place... 0 - https://github.com/FrenkelS/Doom8088ST/issues/21 Daniel Palmer (2): tools/nolibc: Add fread() to stdio.h tools/nolibc: Add fseek() to stdio.h tools/include/nolibc/stdio.h | 54 +++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) -- 2.51.0
On 2026-01-04 17:38:35+0900, Daniel Palmer wrote: > Using nolibc on nommu 68000, something I'm trying to build[0] wanted fread() and fseek() > so I added them, they seem to work so I'm sharing them. Not sure if I need to add > tests or something? Maybe there is a reason these weren't implemented in the first place... Thanks! These look good in general, I'll reply inline with some comments. Please also do add some tests. > 0 - https://github.com/FrenkelS/Doom8088ST/issues/21 > > Daniel Palmer (2): > tools/nolibc: Add fread() to stdio.h > tools/nolibc: Add fseek() to stdio.h > > tools/include/nolibc/stdio.h | 54 +++++++++++++++++++++++++++++++++++- > 1 file changed, 53 insertions(+), 1 deletion(-) > > -- > 2.51.0 >
Hi Thomas,
On Sun, 4 Jan 2026 at 18:11, Thomas Weißschuh <linux@weissschuh.net> wrote:
> Please also do add some tests.
Would a single function test that exercises the new functions be
enough? Something like this:
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -877,6 +877,45 @@ int test_file_stream(void)
return 0;
}
+int test_file_stream_wsr(void)
+{
+ const char dataout[] = "foo";
+ const size_t datasz = sizeof(dataout);
+ char datain[datasz];
+ FILE *f;
+ int r;
+
+ f = fopen("/tmp/file_stream_test", "w+");
+ if (!f)
+ return -1;
+
+ r = fwrite(dataout, 1, datasz, f);
+ if (r != datasz)
+ goto fail;
+
+ r = fseek(f, 0, SEEK_SET);
+ if (r)
+ goto fail;
+
+ r = fread(datain, 1, datasz, f);
+ if (r != datasz)
+ goto fail;
+
+ if (memcmp(datain, dataout, datasz) != 0)
+ goto fail;
+
+ r = fclose(f);
+ if (r == EOF)
+ return -1;
+
+ return 0;
+
+fail:
+ fclose(f);
+ return -1;
+}
+
Cheers,
Daniel
On 2026-01-04 20:12:11+0900, Daniel Palmer wrote:
> Hi Thomas,
>
> On Sun, 4 Jan 2026 at 18:11, Thomas Weißschuh <linux@weissschuh.net> wrote:
> > Please also do add some tests.
>
> Would a single function test that exercises the new functions be
> enough? Something like this:
That example looks good. But please use O_TMPFILE for the test file, to
make the test more robust and also test fdopen().
You can also return different error numbers depending on the failure to
make debugging easier.
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> @@ -877,6 +877,45 @@ int test_file_stream(void)
> return 0;
> }
>
> +int test_file_stream_wsr(void)
> +{
> + const char dataout[] = "foo";
> + const size_t datasz = sizeof(dataout);
> + char datain[datasz];
> + FILE *f;
> + int r;
> +
> + f = fopen("/tmp/file_stream_test", "w+");
> + if (!f)
> + return -1;
> +
> + r = fwrite(dataout, 1, datasz, f);
> + if (r != datasz)
> + goto fail;
> +
> + r = fseek(f, 0, SEEK_SET);
> + if (r)
> + goto fail;
> +
> + r = fread(datain, 1, datasz, f);
> + if (r != datasz)
> + goto fail;
> +
> + if (memcmp(datain, dataout, datasz) != 0)
> + goto fail;
> +
> + r = fclose(f);
> + if (r == EOF)
> + return -1;
> +
> + return 0;
> +
> +fail:
> + fclose(f);
> + return -1;
> +}
> +
>
> Cheers,
>
> Daniel
Hi Daniel,
On Sun, Jan 04, 2026 at 08:12:11PM +0900, Daniel Palmer wrote:
> Hi Thomas,
>
> On Sun, 4 Jan 2026 at 18:11, Thomas Weißschuh <linux@weissschuh.net> wrote:
> > Please also do add some tests.
>
> Would a single function test that exercises the new functions be
> enough? Something like this:
>
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> @@ -877,6 +877,45 @@ int test_file_stream(void)
> return 0;
> }
>
> +int test_file_stream_wsr(void)
> +{
> + const char dataout[] = "foo";
> + const size_t datasz = sizeof(dataout);
> + char datain[datasz];
> + FILE *f;
> + int r;
> +
> + f = fopen("/tmp/file_stream_test", "w+");
> + if (!f)
> + return -1;
> +
> + r = fwrite(dataout, 1, datasz, f);
> + if (r != datasz)
> + goto fail;
> +
> + r = fseek(f, 0, SEEK_SET);
> + if (r)
> + goto fail;
> +
> + r = fread(datain, 1, datasz, f);
> + if (r != datasz)
> + goto fail;
> +
> + if (memcmp(datain, dataout, datasz) != 0)
> + goto fail;
> +
> + r = fclose(f);
> + if (r == EOF)
> + return -1;
> +
> + return 0;
> +
> +fail:
> + fclose(f);
> + return -1;
> +}
> +
In general it's preferable when tests focus on a specific syscall or
function, so that when a failure is reported, it's easier to figure
what we broke. But I agree it's not always easy, especially when
resources are allocated and released, like here. I can hardly propose
better. Please also keep in mind that sometimes we also want to validate
certain error cases (e.g. if opening a file in read-only mode, writing
to it should fail).
Hoping this helps,
Willy
© 2016 - 2026 Red Hat, Inc.