[libc-commits] [libc] [libc] Basic file IO support for bare-metal (PR #221211)

via libc-commits libc-commits at lists.llvm.org
Fri Sep 4 05:20:43 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Volodymyr Turanskyy (voltur01)

<details>
<summary>Changes</summary>

This adds embedding API for file IO support to bare-metal LLVM libc. The approach was discussed in https://discourse.llvm.org/t/rfc-llvm-libc-bare-metal-file-io-support-prototype/91662 and tested with Arm Toolchain for Embedded semihosting implementation.

The embedding API libc/src/__support/OSUtil/baremetal/io.h that has read and write hooks for standard streams is extended with these functions:

- __llvm_libc_stdio_open
- __llvm_libc_stdio_close
- __llvm_libc_stdio_seek
- __llvm_libc_stdio_set_buffer
- __llvm_libc_stdio_flush
- __llvm_libc_stdio_ungetc
- __llvm_libc_stdio_remove
- __llvm_libc_stdio_rename

which map naturally to the API expected by picolibc as another bare-metal library and Arm semihosting https://github.com/ARM-software/abi-aa/blob/main/semihosting/semihosting.rst#semihosting-operations

These are used to implement the following additional C library functions that are enough to implement file IO required by libc++ fstream:

- fopen
- fclose
- fseek
- fseeko
- ftell
- ftello
- setbuf
- setvbuf
- fflush

also rename and remove functions that are readily available in the semihosting API.

__llvm_libc_stdio_ungetc is a special case: libc still provides the single char ungetc for stdin, however an application can optionally implement the full ungetc support which would be important if buffering is implemented.

The embedding API uses opaque pointer as a cookie, which is up to the application to define. For example, the semihosting implementation keeps a small struct with either just the semihosting handle for standard streams or also current position to support seeking for file streams.

An implementation may provide own buffering by default or through the buffering management functions (which are also required by C++ fstream).

An implementation can use the struct of function pointers pattern for the cookie to easily implement support for multiple types of file systems, e.g. UART, flash or FAT.

Assisted-by: codex, reviewed and tested with ATfE by me.

---

Patch is 25.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221211.diff


19 Files Affected:

- (modified) libc/config/baremetal/aarch64/entrypoints.txt (+9) 
- (modified) libc/config/baremetal/arm/entrypoints.txt (+9) 
- (modified) libc/config/baremetal/riscv/entrypoints.txt (+1) 
- (modified) libc/src/__support/OSUtil/baremetal/io.h (+43-2) 
- (modified) libc/src/stdio/CMakeLists.txt (+2-26) 
- (modified) libc/src/stdio/baremetal/CMakeLists.txt (+102-1) 
- (added) libc/src/stdio/baremetal/fclose.cpp (+26) 
- (modified) libc/src/stdio/baremetal/fflush.cpp (+9-5) 
- (modified) libc/src/stdio/baremetal/file_internal.cpp (+7-6) 
- (added) libc/src/stdio/baremetal/fopen.cpp (+39) 
- (added) libc/src/stdio/baremetal/fseek.cpp (+38) 
- (added) libc/src/stdio/baremetal/fseeko.cpp (+37) 
- (added) libc/src/stdio/baremetal/ftell.cpp (+38) 
- (added) libc/src/stdio/baremetal/ftello.cpp (+38) 
- (modified) libc/src/stdio/baremetal/remove.cpp (+16-4) 
- (added) libc/src/stdio/baremetal/rename.cpp (+32) 
- (added) libc/src/stdio/baremetal/setbuf.cpp (+28) 
- (added) libc/src/stdio/baremetal/setvbuf.cpp (+27) 
- (modified) libc/src/stdio/generic/CMakeLists.txt (+26) 


``````````diff
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index b9822e26199f0..5117a51781d91 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -128,14 +128,22 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.feof
     libc.src.stdio.ferror
     libc.src.stdio.fflush
+    libc.src.stdio.fclose
     libc.src.stdio.fgetc
     libc.src.stdio.fgets
     libc.src.stdio.fprintf
     libc.src.stdio.fputc
     libc.src.stdio.fputs
+    libc.src.stdio.fopen
     libc.src.stdio.fread
     libc.src.stdio.fscanf
     libc.src.stdio.fwrite
+    libc.src.stdio.fseek
+    libc.src.stdio.fseeko
+    libc.src.stdio.ftell
+    libc.src.stdio.ftello
+    libc.src.stdio.setbuf
+    libc.src.stdio.setvbuf
     libc.src.stdio.getc
     libc.src.stdio.getchar
     libc.src.stdio.printf
@@ -143,6 +151,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.putchar
     libc.src.stdio.puts
     libc.src.stdio.remove
+    libc.src.stdio.rename
     libc.src.stdio.scanf
     libc.src.stdio.snprintf
     libc.src.stdio.sprintf
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index cc9f0a5031e5a..2194ac647a2e9 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -128,14 +128,22 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.feof
     libc.src.stdio.ferror
     libc.src.stdio.fflush
+    libc.src.stdio.fclose
     libc.src.stdio.fgetc
     libc.src.stdio.fgets
     libc.src.stdio.fprintf
     libc.src.stdio.fputc
     libc.src.stdio.fputs
+    libc.src.stdio.fopen
     libc.src.stdio.fread
     libc.src.stdio.fscanf
     libc.src.stdio.fwrite
+    libc.src.stdio.fseek
+    libc.src.stdio.fseeko
+    libc.src.stdio.ftell
+    libc.src.stdio.ftello
+    libc.src.stdio.setbuf
+    libc.src.stdio.setvbuf
     libc.src.stdio.getc
     libc.src.stdio.getchar
     libc.src.stdio.printf
@@ -143,6 +151,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.putchar
     libc.src.stdio.puts
     libc.src.stdio.remove
+    libc.src.stdio.rename
     libc.src.stdio.scanf
     libc.src.stdio.snprintf
     libc.src.stdio.sprintf
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 7a7746ccc3829..23803b3e376b9 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -141,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.putchar
     libc.src.stdio.puts
     libc.src.stdio.remove
+    libc.src.stdio.rename
     libc.src.stdio.scanf
     libc.src.stdio.snprintf
     libc.src.stdio.sprintf
diff --git a/libc/src/__support/OSUtil/baremetal/io.h b/libc/src/__support/OSUtil/baremetal/io.h
index 5e691f26060eb..af64d61b7e1f9 100644
--- a/libc/src/__support/OSUtil/baremetal/io.h
+++ b/libc/src/__support/OSUtil/baremetal/io.h
@@ -9,8 +9,9 @@
 #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 "hdr/types/off_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/ssize_t.h"
 #include "src/__support/CPP/string_view.h"
 #include "src/__support/macros/config.h"
 
@@ -47,10 +48,50 @@ namespace LIBC_NAMESPACE_DECL {
 
 struct __llvm_libc_stdio_cookie;
 
+// On success, store a non-null application-owned cookie in `cookie` and return
+// 0. On failure, return a negative errno value.
+extern "C" int __llvm_libc_stdio_open(const char *path, const char *mode,
+                                      void **cookie);
+
+// Remove the file named by `path`. Return 0 on success or a negative errno
+// value on failure.
+extern "C" int __llvm_libc_stdio_remove(const char *path);
+
+// Rename the file named by `old_path` to `new_path`. Return 0 on success or a
+// negative errno value on failure.
+extern "C" int __llvm_libc_stdio_rename(const char *old_path,
+                                        const char *new_path);
+
+// Return the number of bytes read, which can be less than `size` and is zero at
+// end-of-file. On failure, return a negative errno value.
 extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size);
+
+// Return the number of bytes written, which can be less than `size`. On
+// failure, return a negative errno value.
 extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf,
                                            size_t size);
 
+// Return the resulting absolute file position on success. On failure, return a
+// negative errno value.
+extern "C" off_t __llvm_libc_stdio_seek(void *cookie, off_t offset, int whence);
+
+// Configure buffering for `cookie`. Return 0 on success or nonzero on failure,
+// matching setvbuf. The application owns any supplied buffer.
+extern "C" int __llvm_libc_stdio_set_buffer(void *cookie, char *buffer,
+                                            size_t size, int mode);
+
+// Flush buffered output for `cookie`, or all output streams if `cookie` is
+// null. Return 0 on success or EOF on failure, matching fflush.
+extern "C" int __llvm_libc_stdio_flush(void *cookie);
+
+// Push `c` back onto the input stream for `cookie`. Return `c` on success or
+// EOF on failure, matching ungetc. This hook is optional; when it is absent,
+// LLVM libc provides one byte of pushback for stdin.
+extern "C" [[gnu::weak]] int __llvm_libc_stdio_ungetc(void *cookie, int c);
+
+// Return 0 on success or EOF on failure, matching fclose.
+extern "C" int __llvm_libc_stdio_close(void *cookie);
+
 void write_to_stderr(cpp::string_view msg);
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 3ef6e4f7b7d01..22de2c4b40384 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -67,32 +67,6 @@ add_entrypoint_object(
     libc.src.__support.File.file
 )
 
-add_entrypoint_object(
-  setbuf
-  SRCS
-    setbuf.cpp
-  HDRS
-    setbuf.h
-  DEPENDS
-    libc.src.errno.errno
-    libc.hdr.types.off_t
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
-add_entrypoint_object(
-  setvbuf
-  SRCS
-    setvbuf.cpp
-  HDRS
-    setvbuf.h
-  DEPENDS
-    libc.src.errno.errno
-    libc.hdr.types.FILE
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
 add_entrypoint_object(
   sscanf
   SRCS
@@ -274,6 +248,8 @@ add_stdio_entrypoint_object(ftell)
 add_stdio_entrypoint_object(fseeko)
 add_stdio_entrypoint_object(fileno)
 add_stdio_entrypoint_object(ftello)
+add_stdio_entrypoint_object(setbuf)
+add_stdio_entrypoint_object(setvbuf)
 add_stdio_entrypoint_object(fflush)
 add_stdio_entrypoint_object(clearerr)
 add_stdio_entrypoint_object(clearerr_unlocked)
diff --git a/libc/src/stdio/baremetal/CMakeLists.txt b/libc/src/stdio/baremetal/CMakeLists.txt
index d26cdbb0f9d51..2d8b5d94119de 100644
--- a/libc/src/stdio/baremetal/CMakeLists.txt
+++ b/libc/src/stdio/baremetal/CMakeLists.txt
@@ -10,6 +10,91 @@ add_object_library(
     libc.src.__support.OSUtil.osutil
 )
 
+add_entrypoint_object(
+  fopen
+  SRCS fopen.cpp
+  HDRS ../fopen.h
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.macros.config
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  fclose
+  SRCS fclose.cpp
+  HDRS ../fclose.h
+  DEPENDS libc.src.__support.OSUtil.osutil libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
+  fseek
+  SRCS fseek.cpp
+  HDRS ../fseek.h
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.macros.config
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  ftell
+  SRCS ftell.cpp
+  HDRS ../ftell.h
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.stdio_macros
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.macros.config
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  fseeko
+  SRCS fseeko.cpp
+  HDRS ../fseeko.h
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.macros.config
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  ftello
+  SRCS ftello.cpp
+  HDRS ../ftello.h
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.stdio_macros
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.macros.config
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  setbuf
+  SRCS setbuf.cpp
+  HDRS ../setbuf.h
+  DEPENDS
+    libc.hdr.stdio_macros
+    libc.hdr.types.FILE
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
+  setvbuf
+  SRCS setvbuf.cpp
+  HDRS ../setvbuf.h
+  DEPENDS
+    libc.hdr.types.FILE
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.macros.config
+)
+
 add_header_library(
   vfprintf_internal
   HDRS
@@ -98,6 +183,8 @@ add_entrypoint_object(
     ../fflush.h
   DEPENDS
     .file_internal
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.macros.config
 )
 
 add_entrypoint_object(
@@ -208,7 +295,21 @@ add_entrypoint_object(
   HDRS
     ../remove.h
   DEPENDS
-    libc.include.stdio
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.libc_errno
+    libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
+  rename
+  SRCS
+    rename.cpp
+  HDRS
+    ../rename.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.libc_errno
+    libc.src.__support.macros.config
 )
 
 set(printf_srcs printf.cpp)
diff --git a/libc/src/stdio/baremetal/fclose.cpp b/libc/src/stdio/baremetal/fclose.cpp
new file mode 100644
index 0000000000000..c7a1e8f7dbc15
--- /dev/null
+++ b/libc/src/stdio/baremetal/fclose.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the bare-metal implementation of fclose.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/fclose.h"
+
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, fclose, (::FILE * stream)) {
+  return __llvm_libc_stdio_close(stream);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/fflush.cpp b/libc/src/stdio/baremetal/fflush.cpp
index 4a39c25ae11c9..90f2cbf73248c 100644
--- a/libc/src/stdio/baremetal/fflush.cpp
+++ b/libc/src/stdio/baremetal/fflush.cpp
@@ -1,22 +1,26 @@
-//===-- Implementation of fflush for baremetal -----------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
 //
 // 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
 //
 //===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the bare-metal implementation of fflush.
+///
+//===----------------------------------------------------------------------===//
 
 #include "src/stdio/fflush.h"
 
+#include "src/__support/OSUtil/io.h"
 #include "src/__support/common.h"
+#include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
-// Baremetal uses unbuffered I/O, so there is nothing to flush.
 LLVM_LIBC_FUNCTION(int, fflush, (::FILE * stream)) {
-  (void)stream;
-  // TODO: Shall we have an embedding API for fflush?
-  return 0;
+  return __llvm_libc_stdio_flush(stream);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/file_internal.cpp b/libc/src/stdio/baremetal/file_internal.cpp
index c12ab1c90d55b..dc77be359f06d 100644
--- a/libc/src/stdio/baremetal/file_internal.cpp
+++ b/libc/src/stdio/baremetal/file_internal.cpp
@@ -13,12 +13,10 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-// Out of standard streams only stdin supports ungetc,
-// because stdin is readable - ungetc on stdout/stderr is undefined.
-// Only one value is required by the C standard to be stored by ungetc.
-// This minimal implementation only handles stdin and returns error on all
-// other streams.
-// TODO: Shall we have an embedding API for ungetc?
+// The fallback handles stdin only because it is the only readable standard
+// stream. The C standard requires only one byte of pushback. Applications that
+// need pushback for other streams or integrate it with their input buffering
+// can provide __llvm_libc_stdio_ungetc instead.
 
 static cpp::optional<unsigned char> ungetc_state_stdin;
 
@@ -38,6 +36,9 @@ int push_ungetc_value(::FILE *stream, int c) {
   if (c == EOF || stream == nullptr)
     return EOF;
 
+  if (__llvm_libc_stdio_ungetc != nullptr)
+    return __llvm_libc_stdio_ungetc(stream, c);
+
   if (stream != stdin)
     return EOF;
 
diff --git a/libc/src/stdio/baremetal/fopen.cpp b/libc/src/stdio/baremetal/fopen.cpp
new file mode 100644
index 0000000000000..9f931df97a48a
--- /dev/null
+++ b/libc/src/stdio/baremetal/fopen.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the bare-metal implementation of fopen.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/fopen.h"
+
+#include "hdr/errno_macros.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(::FILE *, fopen,
+                   (const char *__restrict path, const char *__restrict mode)) {
+  if (path == nullptr || mode == nullptr || mode[0] == '\0') {
+    libc_errno = EINVAL;
+    return nullptr;
+  }
+  void *cookie = nullptr;
+  int result = __llvm_libc_stdio_open(path, mode, &cookie);
+  if (result != 0 || cookie == nullptr) {
+    libc_errno = result != 0 ? -result : EINVAL;
+    return nullptr;
+  }
+  return reinterpret_cast<::FILE *>(cookie);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/fseek.cpp b/libc/src/stdio/baremetal/fseek.cpp
new file mode 100644
index 0000000000000..540c3cb70fbe5
--- /dev/null
+++ b/libc/src/stdio/baremetal/fseek.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the bare-metal implementation of fseek.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/fseek.h"
+
+#include "hdr/errno_macros.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, fseek, (::FILE * stream, long offset, int whence)) {
+  if (stream == nullptr) {
+    libc_errno = EINVAL;
+    return -1;
+  }
+  off_t result =
+      __llvm_libc_stdio_seek(stream, static_cast<off_t>(offset), whence);
+  if (result < 0) {
+    libc_errno = static_cast<int>(-result);
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/fseeko.cpp b/libc/src/stdio/baremetal/fseeko.cpp
new file mode 100644
index 0000000000000..42c87aebe6911
--- /dev/null
+++ b/libc/src/stdio/baremetal/fseeko.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the bare-metal implementation of fseeko.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/fseeko.h"
+
+#include "hdr/errno_macros.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, fseeko, (::FILE * stream, off_t offset, int whence)) {
+  if (stream == nullptr) {
+    libc_errno = EINVAL;
+    return -1;
+  }
+  off_t result = __llvm_libc_stdio_seek(stream, offset, whence);
+  if (result < 0) {
+    libc_errno = static_cast<int>(-result);
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/ftell.cpp b/libc/src/stdio/baremetal/ftell.cpp
new file mode 100644
index 0000000000000..8b062d955a4f3
--- /dev/null
+++ b/libc/src/stdio/baremetal/ftell.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the bare-metal implementation of ftell.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/ftell.h"
+
+#include "hdr/errno_macros.h"
+#include "hdr/stdio_macros.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long, ftell, (::FILE * stream)) {
+  if (stream == nullptr) {
+    libc_errno = EINVAL;
+    return -1;
+  }
+  off_t result = __llvm_libc_stdio_seek(stream, 0, SEEK_CUR);
+  if (result < 0) {
+    libc_errno = static_cast<int>(-result);
+    return -1;
+  }
+  return static_cast<long>(result);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/ftello.cpp b/libc/src/stdio/baremetal/ftello.cpp
new file mode 100644
index 0000000000000..0f5db4872a112
--- /dev/null
+++ b/libc/src/stdio/baremetal/ftello.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the bare-metal implementation of ftello.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/ftello.h"
+
+#include "hdr/errno_macros.h"
+#include "hdr/stdio_macros.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(off_t, ftello, (::FILE * stream)) {
+  if (stream == nullptr) {
+    libc_errno = EINVAL;
+    return static_cast<off_t>(-1);
+  }
+  off_t result = __llvm_libc_stdio_seek(stream, 0, SEEK_CUR);
+  if (result < 0) {
+    libc_errno = static_cast<int>(-result);
+    return static_cast<off_t>(-1);
+  }
+  return result;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/remove.cpp b/libc/s...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/221211


More information about the libc-commits mailing list