diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt index f2ed5025872d..a67772b4507f 100644 --- a/libc/config/baremetal/arm/entrypoints.txt +++ b/libc/config/baremetal/arm/entrypoints.txt @@ -83,6 +83,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.inttypes.strtoumax # stdio.h entrypoints + libc.src.stdio.getchar libc.src.stdio.printf libc.src.stdio.putchar libc.src.stdio.puts diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt index 948395560fad..eaa028c09dcd 100644 --- a/libc/config/baremetal/riscv/entrypoints.txt +++ b/libc/config/baremetal/riscv/entrypoints.txt @@ -79,6 +79,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.inttypes.strtoumax # stdio.h entrypoints + libc.src.stdio.getchar libc.src.stdio.printf libc.src.stdio.putchar libc.src.stdio.puts diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp b/libc/src/__support/OSUtil/baremetal/io.cpp index 347c7d405b0a..5dd92e4a56ce 100644 --- a/libc/src/__support/OSUtil/baremetal/io.cpp +++ b/libc/src/__support/OSUtil/baremetal/io.cpp @@ -11,10 +11,19 @@ #include "src/__support/CPP/string_view.h" // This is intended to be provided by the vendor. + +extern struct __llvm_libc_stdin __llvm_libc_stdin; +extern "C" ssize_t __llvm_libc_stdin_read(void *cookie, char *buf, size_t size); + extern "C" void __llvm_libc_log_write(const char *msg, size_t len); namespace LIBC_NAMESPACE { +ssize_t read_from_stdin(char *buf, size_t size) { + return __llvm_libc_stdin_read(reinterpret_cast(&__llvm_libc_stdin), + buf, size); +} + void write_to_stderr(cpp::string_view msg) { __llvm_libc_log_write(msg.data(), msg.size()); } diff --git a/libc/src/__support/OSUtil/baremetal/io.h b/libc/src/__support/OSUtil/baremetal/io.h index 87534641b1fa..b9ae0bde502b 100644 --- a/libc/src/__support/OSUtil/baremetal/io.h +++ b/libc/src/__support/OSUtil/baremetal/io.h @@ -9,10 +9,13 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_IO_H #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_IO_H +#include "include/llvm-libc-types/size_t.h" +#include "include/llvm-libc-types/ssize_t.h" #include "src/__support/CPP/string_view.h" namespace LIBC_NAMESPACE { +ssize_t read_from_stdin(char *buf, size_t size); void write_to_stderr(cpp::string_view msg); } // namespace LIBC_NAMESPACE diff --git a/libc/src/stdio/baremetal/CMakeLists.txt b/libc/src/stdio/baremetal/CMakeLists.txt index 4acd8873ab75..5ace85d00904 100644 --- a/libc/src/stdio/baremetal/CMakeLists.txt +++ b/libc/src/stdio/baremetal/CMakeLists.txt @@ -1,3 +1,14 @@ +add_entrypoint_object( + getchar + SRCS + getchar.cpp + HDRS + ../getchar.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.__support.CPP.string_view +) + add_entrypoint_object( remove SRCS diff --git a/libc/src/stdio/baremetal/getchar.cpp b/libc/src/stdio/baremetal/getchar.cpp new file mode 100644 index 000000000000..bbd5ba7a954f --- /dev/null +++ b/libc/src/stdio/baremetal/getchar.cpp @@ -0,0 +1,24 @@ +//===-- Baremetal implementation of getchar -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/getchar.h" +#include "src/__support/OSUtil/io.h" + +#include + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, getchar, ()) { + char buf[1]; + auto result = read_from_stdin(buf, sizeof(buf)); + if (result < 0) + return EOF; + return buf[0]; +} + +} // namespace LIBC_NAMESPACE