diff options
-rw-r--r-- | libc/src/__support/OSUtil/baremetal/io.cpp | 50 | ||||
-rw-r--r-- | libc/src/__support/OSUtil/baremetal/io.h | 1 |
2 files changed, 45 insertions, 6 deletions
diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp b/libc/src/__support/OSUtil/baremetal/io.cpp index de278eb..f8ec603 100644 --- a/libc/src/__support/OSUtil/baremetal/io.cpp +++ b/libc/src/__support/OSUtil/baremetal/io.cpp @@ -13,20 +13,58 @@ namespace LIBC_NAMESPACE_DECL { -// This is intended to be provided by the vendor. +// These are intended to be provided by the vendor. +// +// The signature of these types and functions intentionally match `fopencookie` +// which allows the following: +// +// ``` +// struct __llvm_libc_stdio_cookie { ... }; +// ... +// struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie; +// cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read }; +// FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func); +// ... +// struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie; +// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write }; +// FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func); +// ... +// struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie; +// cookie_io_functions_t stderr_func = { .write = __llvm_libc_stdio_write }; +// FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func); +// ``` +// +// At the same time, implementation of functions like `printf` and `scanf` can +// use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid +// the extra indirection. +// +// All three symbols `__llvm_libc_stdin_cookie`, `__llvm_libc_stdout_cookie`, +// and `__llvm_libc_stderr_cookie` must be provided, even if they don't point +// at anything. -extern struct __llvm_libc_stdin __llvm_libc_stdin; -extern "C" ssize_t __llvm_libc_stdin_read(void *cookie, char *buf, size_t size); +struct __llvm_libc_stdio_cookie; -extern "C" void __llvm_libc_log_write(const char *msg, size_t len); +extern struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie; +extern struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie; +extern struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie; + +extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size); +extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf, + size_t size); ssize_t read_from_stdin(char *buf, size_t size) { - return __llvm_libc_stdin_read(reinterpret_cast<void *>(&__llvm_libc_stdin), + return __llvm_libc_stdio_read(static_cast<void *>(&__llvm_libc_stdin_cookie), buf, size); } +void write_to_stdout(cpp::string_view msg) { + __llvm_libc_stdio_write(static_cast<void *>(&__llvm_libc_stdout_cookie), + msg.data(), msg.size()); +} + void write_to_stderr(cpp::string_view msg) { - __llvm_libc_log_write(msg.data(), msg.size()); + __llvm_libc_stdio_write(static_cast<void *>(&__llvm_libc_stderr_cookie), + msg.data(), msg.size()); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/OSUtil/baremetal/io.h b/libc/src/__support/OSUtil/baremetal/io.h index 92bf3db..aed34ec 100644 --- a/libc/src/__support/OSUtil/baremetal/io.h +++ b/libc/src/__support/OSUtil/baremetal/io.h @@ -18,6 +18,7 @@ namespace LIBC_NAMESPACE_DECL { ssize_t read_from_stdin(char *buf, size_t size); void write_to_stderr(cpp::string_view msg); +void write_to_stdout(cpp::string_view msg); } // namespace LIBC_NAMESPACE_DECL |