aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/src/__support/OSUtil/baremetal/io.cpp50
-rw-r--r--libc/src/__support/OSUtil/baremetal/io.h1
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