* [PATCH v2 0/3] nolibc: Add fread() and fseek()
@ 2026-01-05 2:36 Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 1/3] tools/nolibc: Add fread() to stdio.h Daniel Palmer
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Daniel Palmer @ 2026-01-05 2:36 UTC (permalink / raw)
To: w, linux; +Cc: david.laight.linux, linux-kernel, Daniel Palmer
v1 blurb:
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
Changelog:
v2:
- A few style clean ups in fread() requested by Thomas.
- Added a basic test that exercises the new functions. This isn't a complete POSIX
testsuite, just a very basic smoke test. I couldn't think of proper error numbers
for different failure cases (Suggested by Thomas), any ideas appreciated.
Daniel Palmer (3):
tools/nolibc: Add fread() to stdio.h
tools/nolibc: Add fseek() to stdio.h
tools/nolibc: Add a simple test for writing to a FILE and reading it
back
tools/include/nolibc/stdio.h | 53 +++++++++++++++++++-
tools/testing/selftests/nolibc/nolibc-test.c | 53 ++++++++++++++++++++
2 files changed, 105 insertions(+), 1 deletion(-)
--
2.51.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/3] tools/nolibc: Add fread() to stdio.h
2026-01-05 2:36 [PATCH v2 0/3] nolibc: Add fread() and fseek() Daniel Palmer
@ 2026-01-05 2:36 ` Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 2/3] tools/nolibc: Add fseek() " Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 3/3] tools/nolibc: Add a simple test for writing to a FILE and reading it back Daniel Palmer
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Palmer @ 2026-01-05 2:36 UTC (permalink / raw)
To: w, linux; +Cc: david.laight.linux, linux-kernel, Daniel Palmer
Add a very basic version of fread() like we already have for fwrite().
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
tools/include/nolibc/stdio.h | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index 1f16dab2ac88..6904252df97d 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -170,7 +170,7 @@ int putchar(int c)
}
-/* fwrite(), puts(), fputs(). Note that puts() emits '\n' but not fputs(). */
+/* fwrite(), fread(), puts(), fputs(). Note that puts() emits '\n' but not fputs(). */
/* internal fwrite()-like function which only takes a size and returns 0 on
* success or EOF on error. It automatically retries on short writes.
@@ -204,6 +204,38 @@ size_t fwrite(const void *s, size_t size, size_t nmemb, FILE *stream)
return written;
}
+/* internal fread()-like function which only takes a size and returns 0 on
+ * success or EOF on error. It automatically retries on short reads.
+ */
+static __attribute__((unused))
+int _fread(void *buf, size_t size, FILE *stream)
+{
+ int fd = fileno(stream);
+ ssize_t ret;
+
+ while (size) {
+ ret = read(fd, buf, size);
+ if (ret <= 0)
+ return EOF;
+ size -= ret;
+ buf += ret;
+ }
+ return 0;
+}
+
+static __attribute__((unused))
+size_t fread(void *s, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t nread;
+
+ for (nread = 0; nread < nmemb; nread++) {
+ if (_fread(s, size, stream) != 0)
+ break;
+ s += size;
+ }
+ return nread;
+}
+
static __attribute__((unused))
int fputs(const char *s, FILE *stream)
{
--
2.51.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/3] tools/nolibc: Add fseek() to stdio.h
2026-01-05 2:36 [PATCH v2 0/3] nolibc: Add fread() and fseek() Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 1/3] tools/nolibc: Add fread() to stdio.h Daniel Palmer
@ 2026-01-05 2:36 ` Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 3/3] tools/nolibc: Add a simple test for writing to a FILE and reading it back Daniel Palmer
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Palmer @ 2026-01-05 2:36 UTC (permalink / raw)
To: w, linux; +Cc: david.laight.linux, linux-kernel, Daniel Palmer
A very basic wrapper around lseek() that implements fseek().
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
tools/include/nolibc/stdio.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index 6904252df97d..233318b0d0f0 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -272,6 +272,25 @@ char *fgets(char *s, int size, FILE *stream)
}
+/* fseek */
+static __attribute__((unused))
+int fseek(FILE *stream, long offset, int whence)
+{
+ int fd = fileno(stream);
+ off_t ret;
+
+ ret = lseek(fd, offset, whence);
+
+ /* lseek() and fseek() differ in that lseek returns the new
+ * position or -1, fseek() returns either 0 or -1.
+ */
+ if (ret >= 0)
+ return 0;
+
+ return -1;
+}
+
+
/* minimal printf(). It supports the following formats:
* - %[l*]{d,u,c,x,p}
* - %s
--
2.51.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 3/3] tools/nolibc: Add a simple test for writing to a FILE and reading it back
2026-01-05 2:36 [PATCH v2 0/3] nolibc: Add fread() and fseek() Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 1/3] tools/nolibc: Add fread() to stdio.h Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 2/3] tools/nolibc: Add fseek() " Daniel Palmer
@ 2026-01-05 2:36 ` Daniel Palmer
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Palmer @ 2026-01-05 2:36 UTC (permalink / raw)
To: w, linux; +Cc: david.laight.linux, linux-kernel, Daniel Palmer
Add a test that exercises create->write->seek->read to check that using the
stream functions (fwrite() etc) is not totally broken.
The only edge cases this is testing for are:
- Reading the file after writing but without rewinding reads nothing.
- Trying to read more items than the file contains returns the count of
fully read items.
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
tools/testing/selftests/nolibc/nolibc-test.c | 53 ++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 3c5a226dad3a..6d99698005c4 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -877,6 +877,58 @@ 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];
+ int fd, r;
+ FILE *f;
+
+ fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
+ if (fd == -1)
+ return -1;
+
+ f = fdopen(fd, "w+");
+ if (!f)
+ return -1;
+
+ errno = 0;
+ r = fwrite(dataout, 1, datasz, f);
+ if (r != datasz)
+ return -1;
+
+ /* Attempt to read from the file without rewinding,
+ * we should read 0 items.
+ */
+ r = fread(datain, 1, datasz, f);
+ if (r)
+ return -1;
+
+ /* Rewind the file to the start */
+ r = fseek(f, 0, SEEK_SET);
+ if (r)
+ return -1;
+
+ /* Attempt to read back more than was written to
+ * make sure we handle short reads properly.
+ * fread() should return the number of complete items.
+ */
+ r = fread(datain, 1, datasz + 1, f);
+ if (r != datasz)
+ return -1;
+
+ /* Data we read should match the data we just wrote */
+ if (memcmp(datain, dataout, datasz) != 0)
+ return -1;
+
+ r = fclose(f);
+ if (r)
+ return -1;
+
+ return 0;
+}
+
enum fork_type {
FORK_STANDARD,
FORK_VFORK,
@@ -1351,6 +1403,7 @@ int run_syscall(int min, int max)
CASE_TEST(fchdir_stdin); EXPECT_SYSER(1, fchdir(STDIN_FILENO), -1, ENOTDIR); break;
CASE_TEST(fchdir_badfd); EXPECT_SYSER(1, fchdir(-1), -1, EBADF); break;
CASE_TEST(file_stream); EXPECT_SYSZR(1, test_file_stream()); break;
+ CASE_TEST(file_stream_wsr); EXPECT_SYSZR(1, test_file_stream_wsr()); break;
CASE_TEST(fork); EXPECT_SYSZR(1, test_fork(FORK_STANDARD)); break;
CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
CASE_TEST(getdents64_null); EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;
--
2.51.0
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-01-05 2:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-05 2:36 [PATCH v2 0/3] nolibc: Add fread() and fseek() Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 1/3] tools/nolibc: Add fread() to stdio.h Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 2/3] tools/nolibc: Add fseek() " Daniel Palmer
2026-01-05 2:36 ` [PATCH v2 3/3] tools/nolibc: Add a simple test for writing to a FILE and reading it back Daniel Palmer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®