[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250423-nolibc-misc-v1-13-a925bf40297b@linutronix.de>
Date: Wed, 23 Apr 2025 17:01:43 +0200
From: Thomas Weißschuh <thomas.weissschuh@...utronix.de>
To: Willy Tarreau <w@....eu>,
Thomas Weißschuh <linux@...ssschuh.net>,
Shuah Khan <shuah@...nel.org>
Cc: linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org,
Thomas Weißschuh <thomas.weissschuh@...utronix.de>
Subject: [PATCH 13/15] tools/nolibc: add fopen()
This is used in various selftests and will be handy when integrating
those with nolibc.
Only the standard POSIX modes are supported.
No extensions nor the (noop) "b" from ISO C are accepted.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@...utronix.de>
---
tools/include/nolibc/stdio.h | 27 +++++++++++++++++++++++++++
tools/testing/selftests/nolibc/nolibc-test.c | 24 ++++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index 02426682c34bcd82d9556036c6c3e73a6a5a3b4d..86a1132abcd4e5e5b0f821cfe974aca8a6d4966f 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -10,6 +10,7 @@
#include "std.h"
#include "arch.h"
#include "errno.h"
+#include "fcntl.h"
#include "types.h"
#include "sys.h"
#include "stdarg.h"
@@ -52,6 +53,32 @@ FILE *fdopen(int fd, const char *mode __attribute__((unused)))
return (FILE*)(intptr_t)~fd;
}
+static __attribute__((unused))
+FILE *fopen(const char *pathname, const char *mode)
+{
+ int flags, fd;
+
+ if (!strcmp(mode, "r"))
+ flags = O_RDONLY;
+ else if (!strcmp(mode, "w"))
+ flags = O_WRONLY | O_CREAT | O_TRUNC;
+ else if (!strcmp(mode, "a"))
+ flags = O_WRONLY | O_CREAT | O_APPEND;
+ else if (!strcmp(mode, "r+"))
+ flags = O_RDWR;
+ else if (!strcmp(mode, "w+"))
+ flags = O_RDWR | O_CREAT | O_TRUNC;
+ else if (!strcmp(mode, "a+"))
+ flags = O_RDWR | O_CREAT | O_APPEND;
+ else {
+ SET_ERRNO(EINVAL);
+ return NULL;
+ }
+
+ fd = open(pathname, flags, 0666);
+ return fdopen(fd, mode);
+}
+
/* provides the fd of stream. */
static __attribute__((unused))
int fileno(FILE *stream)
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index ab9c3bcffd9750981d68c6d16245d285ce0657c8..f576edc3725b42ce086d6d83d989f38d3fab6eb8 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -856,6 +856,29 @@ int test_getpagesize(void)
return !c;
}
+int test_file_stream(void)
+{
+ FILE *f;
+ int r;
+
+ f = fopen("/dev/null", "r");
+ if (!f)
+ return -1;
+
+ errno = 0;
+ r = fwrite("foo", 1, 3, f);
+ if (r != 0 || errno != EBADF) {
+ fclose(f);
+ return -1;
+ }
+
+ r = fclose(f);
+ if (r == EOF)
+ return -1;
+
+ return 0;
+}
+
int test_fork(void)
{
int status;
@@ -1308,6 +1331,7 @@ int run_syscall(int min, int max)
CASE_TEST(dup3_0); tmp = dup3(0, 100, 0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
CASE_TEST(dup3_m1); tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
CASE_TEST(execve_root); EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break;
+ CASE_TEST(file_stream); EXPECT_SYSZR(1, test_file_stream()); break;
CASE_TEST(fork); EXPECT_SYSZR(1, test_fork()); 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.49.0
Powered by blists - more mailing lists