[libc-commits] [libc] [libc][stdio] Add fopen_s and bootstrap annex k. (PR #152248)

Muhammad Bassiouni via libc-commits libc-commits at lists.llvm.org
Fri Aug 8 02:19:31 PDT 2025


https://github.com/bassiounix updated https://github.com/llvm/llvm-project/pull/152248

>From 11c8abf71a955bd570f8c8ff3c3beb8231cabb87 Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Wed, 6 Aug 2025 07:49:12 +0300
Subject: [PATCH 1/5] [libc] Add fopen_s.

---
 libc/hdr/types/CMakeLists.txt                 | 18 ++++++++
 libc/hdr/types/constraint_handler_t.h         | 14 ++++++
 libc/hdr/types/errno_t.h                      | 14 ++++++
 libc/include/CMakeLists.txt                   |  3 ++
 libc/include/errno.h.def                      |  2 +
 libc/include/llvm-libc-types/CMakeLists.txt   |  4 ++
 .../llvm-libc-types/constraint_handler_t.h    | 17 +++++++
 libc/include/llvm-libc-types/errno_t.h        | 14 ++++++
 libc/include/stdio.yaml                       |  9 ++++
 libc/include/stdlib.yaml                      |  8 ++++
 libc/src/__support/CMakeLists.txt             |  2 +
 libc/src/__support/annex_k/CMakeLists.txt     | 40 +++++++++++++++++
 libc/src/__support/annex_k/abort_handler_s.h  | 41 +++++++++++++++++
 libc/src/__support/annex_k/helper_macros.h    | 43 ++++++++++++++++++
 libc/src/__support/annex_k/ignore_handler_s.h | 23 ++++++++++
 .../annex_k/libc_constraint_hander.h          | 22 ++++++++++
 libc/src/__support/stdio/CMakeLists.txt       |  9 ++++
 libc/src/__support/stdio/fopen.h              | 34 ++++++++++++++
 libc/src/stdio/CMakeLists.txt                 |  8 ++++
 libc/src/stdio/fopen_s.h                      | 23 ++++++++++
 libc/src/stdio/generic/CMakeLists.txt         | 16 +++++--
 libc/src/stdio/generic/fopen.cpp              | 12 +----
 libc/src/stdio/generic/fopen_s.cpp            | 44 +++++++++++++++++++
 libc/src/stdlib/CMakeLists.txt                | 12 +++++
 libc/src/stdlib/set_constraint_handler_s.cpp  | 29 ++++++++++++
 libc/src/stdlib/set_constraint_handler_s.h    | 21 +++++++++
 26 files changed, 469 insertions(+), 13 deletions(-)
 create mode 100644 libc/hdr/types/constraint_handler_t.h
 create mode 100644 libc/hdr/types/errno_t.h
 create mode 100644 libc/include/llvm-libc-types/constraint_handler_t.h
 create mode 100644 libc/include/llvm-libc-types/errno_t.h
 create mode 100644 libc/src/__support/annex_k/CMakeLists.txt
 create mode 100644 libc/src/__support/annex_k/abort_handler_s.h
 create mode 100644 libc/src/__support/annex_k/helper_macros.h
 create mode 100644 libc/src/__support/annex_k/ignore_handler_s.h
 create mode 100644 libc/src/__support/annex_k/libc_constraint_hander.h
 create mode 100644 libc/src/__support/stdio/CMakeLists.txt
 create mode 100644 libc/src/__support/stdio/fopen.h
 create mode 100644 libc/src/stdio/fopen_s.h
 create mode 100644 libc/src/stdio/generic/fopen_s.cpp
 create mode 100644 libc/src/stdlib/set_constraint_handler_s.cpp
 create mode 100644 libc/src/stdlib/set_constraint_handler_s.h

diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 02fe1adc264fb..6cd39d0dca020 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -162,6 +162,24 @@ add_proxy_header_library(
     libc.include.fcntl
 )
 
+add_proxy_header_library(
+  errno_t
+  HDRS
+    errno_t.h
+  FULL_BUILD_DEPENDS
+    libc.include.llvm-libc-types.errno_t
+    libc.include.errno
+)
+
+add_proxy_header_library(
+  constraint_handler_t
+  HDRS
+    constraint_handler_t.h
+  FULL_BUILD_DEPENDS
+    libc.include.llvm-libc-types.constraint_handler_t
+    libc.include.stdlib
+)
+
 add_proxy_header_library(
   fenv_t
   HDRS
diff --git a/libc/hdr/types/constraint_handler_t.h b/libc/hdr/types/constraint_handler_t.h
new file mode 100644
index 0000000000000..df7eaa7abf48b
--- /dev/null
+++ b/libc/hdr/types/constraint_handler_t.h
@@ -0,0 +1,14 @@
+//===-- Proxy for constraint_handler_t ------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_CONSTRAINT_HANDLER_T_H
+#define LLVM_LIBC_HDR_TYPES_CONSTRAINT_HANDLER_T_H
+
+#include "include/llvm-libc-types/constraint_handler_t.h"
+
+#endif // LLVM_LIBC_HDR_TYPES_CONSTRAINT_HANDLER_T_H
diff --git a/libc/hdr/types/errno_t.h b/libc/hdr/types/errno_t.h
new file mode 100644
index 0000000000000..8769819d81474
--- /dev/null
+++ b/libc/hdr/types/errno_t.h
@@ -0,0 +1,14 @@
+//===-- Proxy for errno_t -------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_ERRNO_T_H
+#define LLVM_LIBC_HDR_TYPES_ERRNO_T_H
+
+#include "include/llvm-libc-types/errno_t.h"
+
+#endif // LLVM_LIBC_HDR_TYPES_ERRNO_T_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 74fcea0f15e2f..d33ba79765846 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -290,6 +290,7 @@ add_header_macro(
   DEPENDS
     .llvm-libc-macros.generic_error_number_macros
     .llvm-libc-macros.error_number_macros
+    .llvm-libc-types.errno_t
 )
 
 add_header_macro(
@@ -339,6 +340,7 @@ add_header_macro(
     .llvm-libc-types.off_t
     .llvm-libc-types.size_t
     .llvm-libc-types.ssize_t
+    .llvm-libc-types.errno_t
     .llvm_libc_common_h
 )
 
@@ -358,6 +360,7 @@ add_header_macro(
     .llvm-libc-types.lldiv_t
     .llvm-libc-types.locale_t
     .llvm-libc-types.size_t
+    .llvm-libc-types.constraint_handler_t
     .llvm_libc_common_h
 )
 
diff --git a/libc/include/errno.h.def b/libc/include/errno.h.def
index aa1f6c9e48444..35341c60e38b2 100644
--- a/libc/include/errno.h.def
+++ b/libc/include/errno.h.def
@@ -33,4 +33,6 @@ __END_C_DECLS
 
 #define errno (*__llvm_libc_errno())
 
+#include "llvm-libc-types/errno_t.h"
+
 #endif // LLVM_LIBC_ERRNO_H
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 451beae6f1e6f..dc0650b2bd039 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -289,3 +289,7 @@ add_header(EFI_SYSTEM_TABLE
     .EFI_TABLE_HEADER
     .char16_t
 )
+
+add_header(errno_t HDR errno_t.h)
+
+add_header(constraint_handler_t HDR constraint_handler_t.h DEPENDS .errno_t)
diff --git a/libc/include/llvm-libc-types/constraint_handler_t.h b/libc/include/llvm-libc-types/constraint_handler_t.h
new file mode 100644
index 0000000000000..b3dfeb67067f1
--- /dev/null
+++ b/libc/include/llvm-libc-types/constraint_handler_t.h
@@ -0,0 +1,17 @@
+//===-- Definition of type constraint_handler_t ---------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_CONSTRAINT_HANDLER_T_H
+#define LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_CONSTRAINT_HANDLER_T_H
+
+#include "errno_t.h"
+
+typedef void (*constraint_handler_t)(const char *__restrict msg,
+                                     void *__restrict ptr, errno_t error);
+
+#endif // LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_CONSTRAINT_HANDLER_T_H
diff --git a/libc/include/llvm-libc-types/errno_t.h b/libc/include/llvm-libc-types/errno_t.h
new file mode 100644
index 0000000000000..460f072dbd680
--- /dev/null
+++ b/libc/include/llvm-libc-types/errno_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of type errno_t ----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_ERRNO_T_H
+#define LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_ERRNO_T_H
+
+typedef int errno_t;
+
+#endif // LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_ERRNO_T_H
diff --git a/libc/include/stdio.yaml b/libc/include/stdio.yaml
index 2a0c563709984..7674720b03b68 100644
--- a/libc/include/stdio.yaml
+++ b/libc/include/stdio.yaml
@@ -11,6 +11,7 @@ macros:
     macro_value: stderr
 types:
   - type_name: size_t
+  - type_name: errno_t
   - type_name: off_t
   - type_name: cookie_io_functions_t
   - type_name: FILE
@@ -125,6 +126,14 @@ functions:
     arguments:
       - type: const char *
       - type: const char *
+  - name: fopen_s
+    standards:
+      - stdc
+    return_type: errno_t
+    arguments:
+      - type: FILE *__restrict *__restrict
+      - type: const char *__restrict
+      - type: const char *__restrict
   - name: fopencookie
     standards:
       - GNUExtensions
diff --git a/libc/include/stdlib.yaml b/libc/include/stdlib.yaml
index 3b2ff13c684b1..1e6824950ffd8 100644
--- a/libc/include/stdlib.yaml
+++ b/libc/include/stdlib.yaml
@@ -17,6 +17,8 @@ types:
   - type_name: lldiv_t
   - type_name: locale_t
   - type_name: size_t
+  - type_name: errno_t
+  - type_name: constraint_handler_t
 enums: []
 objects: []
 functions:
@@ -180,6 +182,12 @@ functions:
     return_type: int
     arguments:
       - type: void
+  - name: set_constraint_handler_s
+    standards:
+      - stdc
+    return_type: constraint_handler_t
+    arguments:
+      - type: constraint_handler_t
   - name: srand
     standards:
       - stdc
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 2196d9e23bba7..f2239e7d27ade 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -1,5 +1,7 @@
+add_subdirectory(annex_k)
 add_subdirectory(CPP)
 add_subdirectory(macros)
+add_subdirectory(stdio)
 
 add_header_library(
   libc_errno
diff --git a/libc/src/__support/annex_k/CMakeLists.txt b/libc/src/__support/annex_k/CMakeLists.txt
new file mode 100644
index 0000000000000..b3b472a8dbd16
--- /dev/null
+++ b/libc/src/__support/annex_k/CMakeLists.txt
@@ -0,0 +1,40 @@
+add_header_library(
+  abort_handler_s
+  HDRS
+    abort_handler_s.h
+  DEPENDS
+    libc.hdr.stdio_macros
+    libc.hdr.types.errno_t
+    libc.src.__support.macros.config
+    libc.src.__support.macros.attributes
+    libc.src.__support.File.file
+    libc.src.stdio.fprintf
+    libc.src.stdio.fflush
+    libc.src.stdlib.abort
+)
+
+add_header_library(
+  ignore_handler_s
+  HDRS
+    ignore_handler_s.h
+  DEPENDS
+    libc.hdr.types.errno_t
+    libc.src.__support.libc_errno
+    libc.src.__support.macros.config
+    libc.src.__support.macros.attributes
+)
+
+add_header_library(
+  helper_macros
+  HDRS
+    helper_macros.h
+)
+
+add_header_library(
+  libc_constraint_handler
+  HDRS
+    libc_constraint_handler.h
+  DEPENDS
+    libc.src.__support.annex_k.abort_handler_s
+    libc.hdr.types.errno_t
+)
diff --git a/libc/src/__support/annex_k/abort_handler_s.h b/libc/src/__support/annex_k/abort_handler_s.h
new file mode 100644
index 0000000000000..db3512bb0bca5
--- /dev/null
+++ b/libc/src/__support/annex_k/abort_handler_s.h
@@ -0,0 +1,41 @@
+//===-- Implementation header for abort_handler_s ---------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_ABORT_HANDLER_S_H
+#define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_ABORT_HANDLER_S_H
+
+#include "hdr/stdio_macros.h"
+#include "hdr/types/errno_t.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/fflush.h"
+#include "src/stdio/fprintf.h"
+#include "src/stdlib/abort.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LIBC_INLINE static void abort_handler_s(const char *__restrict msg,
+                                        void *__restrict ptr, errno_t error) {
+  libc_errno = error;
+  fprintf(stderr, "abort_handler_s was called in response to a "
+                  "runtime-constraint violation.\n\n");
+  if (msg)
+    fprintf(stderr, "%s\n", msg);
+  fprintf(stderr,
+          "\n\nNote to end users: This program was terminated as a result\
+      of a bug present in the software. Please reach out to your  \
+      software's vendor to get more help.\n");
+
+  fflush(stderr);
+  abort();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_ANNEX_K_ABORT_HANDLER_S_H
diff --git a/libc/src/__support/annex_k/helper_macros.h b/libc/src/__support/annex_k/helper_macros.h
new file mode 100644
index 0000000000000..e11869549897e
--- /dev/null
+++ b/libc/src/__support/annex_k/helper_macros.h
@@ -0,0 +1,43 @@
+//===-- Helper macros header for constraint violations ----------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_HELPER_MACROS_H
+#define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_HELPER_MACROS_H
+
+#include "libc_constraint_hander.h"
+
+#define _CONSTRAINT_VIOLATION(msg, error_code, ret_code)                       \
+  {                                                                            \
+    libc_errno = error_code;                                                   \
+    libc_constraint_handler(msg, nullptr, error_code);                         \
+    return ret_code;                                                           \
+  }
+
+#define _CONSTRAINT_VIOLATION_IF(expr, error_code, return_code)                \
+  {                                                                            \
+    auto expr_val = expr;                                                      \
+    if (expr_val) {                                                            \
+      libc_errno = error_code;                                                 \
+      libc_constraint_handler(nullptr, nullptr, error_code);                   \
+      return return_code;                                                      \
+    }                                                                          \
+  }
+
+#define _CONSTRAINT_VIOLATION_CLEANUP_IF(expr, cleanup, error_code,            \
+                                         return_code)                          \
+  {                                                                            \
+    auto expr_val = expr;                                                      \
+    if (expr_val) {                                                            \
+      cleanup;                                                                 \
+      libc_errno = error_code;                                                 \
+      libc_constraint_handler(nullptr, nullptr, error_code);                   \
+      return return_code;                                                      \
+    }                                                                          \
+  }
+
+#endif // LLVM_LIBC_SRC___SUPPORT_ANNEX_K_HELPER_MACROS_H
diff --git a/libc/src/__support/annex_k/ignore_handler_s.h b/libc/src/__support/annex_k/ignore_handler_s.h
new file mode 100644
index 0000000000000..7690776429945
--- /dev/null
+++ b/libc/src/__support/annex_k/ignore_handler_s.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for ignore_handler_s --------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_IGNORE_HANDLER_S_H
+#define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_IGNORE_HANDLER_S_H
+
+#include "hdr/types/errno_t.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LIBC_INLINE static void ignore_handler_s(const char *__restrict msg,
+                                         void *__restrict ptr, errno_t error) {}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_ANNEX_K_IGNORE_HANDLER_S_H
diff --git a/libc/src/__support/annex_k/libc_constraint_hander.h b/libc/src/__support/annex_k/libc_constraint_hander.h
new file mode 100644
index 0000000000000..a21b966133104
--- /dev/null
+++ b/libc/src/__support/annex_k/libc_constraint_hander.h
@@ -0,0 +1,22 @@
+//===-- Static header for libc_constraint_handler ---------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDER_H
+#define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDER_H
+
+#include "hdr/types/constraint_handler_t.h"
+#include "src/__support/annex_k/abort_handler_s.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LIBC_INLINE static constraint_handler_t libc_constraint_handler =
+    &abort_handler_s;
+
+}
+
+#endif // LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDER_H
diff --git a/libc/src/__support/stdio/CMakeLists.txt b/libc/src/__support/stdio/CMakeLists.txt
new file mode 100644
index 0000000000000..3bb93b634c1a0
--- /dev/null
+++ b/libc/src/__support/stdio/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_header_library(
+  fopen
+  HDRS
+    fopen.h
+  DEPENDS
+    libc.hdr.types.FILE
+    libc.src.__support.File.file
+    libc.src.__support.libc_errno
+)
diff --git a/libc/src/__support/stdio/fopen.h b/libc/src/__support/stdio/fopen.h
new file mode 100644
index 0000000000000..738b7963db50c
--- /dev/null
+++ b/libc/src/__support/stdio/fopen.h
@@ -0,0 +1,34 @@
+//===-- Common implementation of fopen ------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_STDIO_FOPEN_H
+#define LLVM_LIBC_SRC___SUPPORT_STDIO_FOPEN_H
+
+#include "hdr/types/FILE.h"
+#include "src/__support/File/file.h"
+#include "src/__support/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace stdio_internal {
+
+LIBC_INLINE static constexpr ::FILE *fopen(const char *__restrict name,
+                                           const char *__restrict mode) {
+  auto result = LIBC_NAMESPACE::openfile(name, mode);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return nullptr;
+  }
+  return reinterpret_cast<::FILE *>(result.value());
+}
+
+} // namespace stdio_internal
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_STDIO_FOPEN_H
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index b0a6ef1e291b5..32810b41b8866 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -204,6 +204,14 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.fdopen
 )
 
+add_entrypoint_object(
+  fopen_s
+  HDRS
+    fopen_s.h
+  DEPENDS
+    .generic.fopen_s
+)
+
 # These entrypoints have multiple potential implementations.
 add_stdio_entrypoint_object(feof)
 add_stdio_entrypoint_object(feof_unlocked)
diff --git a/libc/src/stdio/fopen_s.h b/libc/src/stdio/fopen_s.h
new file mode 100644
index 0000000000000..19f3f9cf1ee7c
--- /dev/null
+++ b/libc/src/stdio/fopen_s.h
@@ -0,0 +1,23 @@
+//===-- Implementation header of fopen_s ------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDIO_FOPEN_S_H
+#define LLVM_LIBC_SRC_STDIO_FOPEN_S_H
+
+#include "hdr/types/FILE.h"
+#include "include/llvm-libc-types/errno_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+errno_t fopen_s(FILE *__restrict *__restrict streamptr,
+                const char *__restrict filename, const char *__restrict mode);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDIO_FOPEN_S_H
diff --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt
index 6361822b61999..0898ae83a76ac 100644
--- a/libc/src/stdio/generic/CMakeLists.txt
+++ b/libc/src/stdio/generic/CMakeLists.txt
@@ -162,9 +162,19 @@ add_generic_entrypoint_object(
   HDRS
     ../fopen.h
   DEPENDS
-    libc.hdr.types.FILE
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
+    libc.src.__support.stdio.fopen
+)
+
+add_generic_entrypoint_object(
+  fopen_s
+  SRCS
+    fopen_s.cpp
+  HDRS
+    ../fopen_s.h
+  DEPENDS
+    libc.src.__support.stdio.fopen
+    libc.src.__support.macros.config
+    libc.src.__support.annex_k.helper_macros
 )
 
 add_generic_entrypoint_object(
diff --git a/libc/src/stdio/generic/fopen.cpp b/libc/src/stdio/generic/fopen.cpp
index 57c85c2e54e16..a1db51a00bde2 100644
--- a/libc/src/stdio/generic/fopen.cpp
+++ b/libc/src/stdio/generic/fopen.cpp
@@ -7,22 +7,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/stdio/fopen.h"
-#include "src/__support/File/file.h"
-
-#include "hdr/types/FILE.h"
-#include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
+#include "src/__support/stdio/fopen.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(::FILE *, fopen,
                    (const char *__restrict name, const char *__restrict mode)) {
-  auto result = LIBC_NAMESPACE::openfile(name, mode);
-  if (!result.has_value()) {
-    libc_errno = result.error();
-    return nullptr;
-  }
-  return reinterpret_cast<::FILE *>(result.value());
+  return stdio_internal::fopen(name, mode);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/generic/fopen_s.cpp b/libc/src/stdio/generic/fopen_s.cpp
new file mode 100644
index 0000000000000..546218ff76f27
--- /dev/null
+++ b/libc/src/stdio/generic/fopen_s.cpp
@@ -0,0 +1,44 @@
+//===-- Implementation of fopen_s -----------------------------------------===//
+//
+// 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/fopen_s.h"
+#include "src/__support/annex_k/helper_macros.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/stdio/fopen.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(errno_t, fopen_s,
+                   (FILE *__restrict *__restrict streamptr,
+                    const char *__restrict filename,
+                    const char *__restrict mode)) {
+  _CONSTRAINT_VIOLATION_IF(streamptr == 0, EINVAL, EINVAL);
+  _CONSTRAINT_VIOLATION_CLEANUP_IF(!mode || !filename, *streamptr = nullptr,
+                                   EINVAL, EINVAL);
+
+  FILE *ret = nullptr;
+
+  if (mode[0] == 'u') {
+    ret = stdio_internal::fopen(filename, mode + 1);
+    if (!ret) {
+      *streamptr = nullptr;
+      return -1;
+    }
+  } else {
+    ret = stdio_internal::fopen(filename, mode);
+    if (!ret) {
+      *streamptr = nullptr;
+      return -1;
+    }
+  }
+
+  *streamptr = ret;
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index aa653c38a8c3f..0165c799b7aa8 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -652,3 +652,15 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.system
 )
+
+add_entrypoint_object(
+  set_constraint_handler_s
+  SRCS
+    set_constraint_handler_s.cpp
+  HDRS
+    set_constraint_handler_s.h
+  DEPENDS
+    libc.src.__support.annex_k.abort_handler_s
+    libc.src.__support.annex_k.libc_constraint_handler
+    libc.src.__support.macros.config
+)
diff --git a/libc/src/stdlib/set_constraint_handler_s.cpp b/libc/src/stdlib/set_constraint_handler_s.cpp
new file mode 100644
index 0000000000000..5d215a58461be
--- /dev/null
+++ b/libc/src/stdlib/set_constraint_handler_s.cpp
@@ -0,0 +1,29 @@
+//===-- Implementation of set_constraint_handler_s ------------------------===//
+//
+// 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 "set_constraint_handler_s.h"
+#include "src/__support/annex_k/abort_handler_s.h"
+#include "src/__support/annex_k/libc_constraint_hander.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(constraint_handler_t, set_constraint_handler_s,
+                   (constraint_handler_t handler)) {
+  constraint_handler_t previous_handler = libc_constraint_handler;
+
+  if (!handler) {
+    libc_constraint_handler = &abort_handler_s;
+  } else {
+    libc_constraint_handler = handler;
+  }
+
+  return previous_handler;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/set_constraint_handler_s.h b/libc/src/stdlib/set_constraint_handler_s.h
new file mode 100644
index 0000000000000..6da7e85bd693a
--- /dev/null
+++ b/libc/src/stdlib/set_constraint_handler_s.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for set_constraint_handler_s ------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRTOULL_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOULL_H
+
+#include "hdr/types/constraint_handler_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+constraint_handler_t set_constraint_handler_s(constraint_handler_t handler);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOULL_H

>From 90fc6a78156f53f319ac4318b36179911bd00e56 Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Wed, 6 Aug 2025 11:35:03 +0300
Subject: [PATCH 2/5] add function to linux x86 entrypoint

---
 libc/config/linux/x86_64/entrypoints.txt        |  3 +++
 libc/include/CMakeLists.txt                     |  1 +
 libc/include/llvm-libc-types/CMakeLists.txt     |  1 +
 libc/include/llvm-libc-types/rsize_t.h          | 14 ++++++++++++++
 libc/include/stdlib.yaml                        | 17 +++++++++++++++++
 libc/src/__support/annex_k/CMakeLists.txt       |  2 +-
 libc/src/__support/annex_k/abort_handler_s.h    |  3 ++-
 libc/src/__support/annex_k/helper_macros.h      |  2 +-
 ...raint_hander.h => libc_constraint_handler.h} |  2 +-
 libc/src/stdio/CMakeLists.txt                   |  9 +--------
 libc/src/stdlib/set_constraint_handler_s.cpp    |  2 +-
 11 files changed, 43 insertions(+), 13 deletions(-)
 create mode 100644 libc/include/llvm-libc-types/rsize_t.h
 rename libc/src/__support/annex_k/{libc_constraint_hander.h => libc_constraint_handler.h} (93%)

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index ec41069e98c91..b64e956fa3e96 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -198,6 +198,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.qsort
     libc.src.stdlib.qsort_r
     libc.src.stdlib.rand
+    libc.src.stdlib.set_constraint_handler_s
     libc.src.stdlib.srand
     libc.src.stdlib.strfromd
     libc.src.stdlib.strfromf
@@ -1127,6 +1128,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.stdio.fileno
     libc.src.stdio.flockfile
     libc.src.stdio.fopen
+    libc.src.stdio.fopen_s
     libc.src.stdio.fopencookie
     libc.src.stdio.fputc
     libc.src.stdio.fputs
@@ -1162,6 +1164,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.stdlib.exit
     libc.src.stdlib.getenv
     libc.src.stdlib.quick_exit
+    libc.src.stdlib.set_constraint_handler_s
 
     # signal.h entrypoints
     libc.src.signal.kill
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index d33ba79765846..7d8186e215453 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -360,6 +360,7 @@ add_header_macro(
     .llvm-libc-types.lldiv_t
     .llvm-libc-types.locale_t
     .llvm-libc-types.size_t
+    .llvm-libc-types.rsize_t
     .llvm-libc-types.constraint_handler_t
     .llvm_libc_common_h
 )
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index dc0650b2bd039..6480491f6ea4c 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_header(off64_t HDR off64_t.h)
 add_header(size_t HDR size_t.h)
+add_header(rsize_t HDR rsize_t.h)
 add_header(ssize_t HDR ssize_t.h)
 add_header(__atfork_callback_t HDR __atfork_callback_t.h)
 add_header(__search_compare_t HDR __search_compare_t.h)
diff --git a/libc/include/llvm-libc-types/rsize_t.h b/libc/include/llvm-libc-types/rsize_t.h
new file mode 100644
index 0000000000000..dca61c4f76a05
--- /dev/null
+++ b/libc/include/llvm-libc-types/rsize_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of rsize_t types ---------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_RSIZE_T_H
+#define LLVM_LIBC_TYPES_RSIZE_T_H
+
+typedef __SIZE_TYPE__ rsize_t;
+
+#endif // LLVM_LIBC_TYPES_RSIZE_T_H
diff --git a/libc/include/stdlib.yaml b/libc/include/stdlib.yaml
index 1e6824950ffd8..c225a53b87f39 100644
--- a/libc/include/stdlib.yaml
+++ b/libc/include/stdlib.yaml
@@ -17,6 +17,7 @@ types:
   - type_name: lldiv_t
   - type_name: locale_t
   - type_name: size_t
+  - type_name: rsize_t
   - type_name: errno_t
   - type_name: constraint_handler_t
 enums: []
@@ -188,6 +189,22 @@ functions:
     return_type: constraint_handler_t
     arguments:
       - type: constraint_handler_t
+  - name: abort_handler_s
+    standards:
+      - stdc
+    return_type: void
+    arguments:
+      - type: const char *__restrict
+      - type: void *__restrict
+      - type: errno_t
+  - name: ignore_handler_s
+    standards:
+      - stdc
+    return_type: void
+    arguments:
+      - type: const char *__restrict
+      - type: void *__restrict
+      - type: errno_t
   - name: srand
     standards:
       - stdc
diff --git a/libc/src/__support/annex_k/CMakeLists.txt b/libc/src/__support/annex_k/CMakeLists.txt
index b3b472a8dbd16..8ab4296f41fe5 100644
--- a/libc/src/__support/annex_k/CMakeLists.txt
+++ b/libc/src/__support/annex_k/CMakeLists.txt
@@ -35,6 +35,6 @@ add_header_library(
   HDRS
     libc_constraint_handler.h
   DEPENDS
-    libc.src.__support.annex_k.abort_handler_s
+    .abort_handler_s
     libc.hdr.types.errno_t
 )
diff --git a/libc/src/__support/annex_k/abort_handler_s.h b/libc/src/__support/annex_k/abort_handler_s.h
index db3512bb0bca5..731f859c537ec 100644
--- a/libc/src/__support/annex_k/abort_handler_s.h
+++ b/libc/src/__support/annex_k/abort_handler_s.h
@@ -21,7 +21,8 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LIBC_INLINE static void abort_handler_s(const char *__restrict msg,
-                                        void *__restrict ptr, errno_t error) {
+                                        [[maybe_unused]] void *__restrict ptr,
+                                        errno_t error) {
   libc_errno = error;
   fprintf(stderr, "abort_handler_s was called in response to a "
                   "runtime-constraint violation.\n\n");
diff --git a/libc/src/__support/annex_k/helper_macros.h b/libc/src/__support/annex_k/helper_macros.h
index e11869549897e..b359acb95c32c 100644
--- a/libc/src/__support/annex_k/helper_macros.h
+++ b/libc/src/__support/annex_k/helper_macros.h
@@ -9,7 +9,7 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_HELPER_MACROS_H
 #define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_HELPER_MACROS_H
 
-#include "libc_constraint_hander.h"
+#include "libc_constraint_handler.h"
 
 #define _CONSTRAINT_VIOLATION(msg, error_code, ret_code)                       \
   {                                                                            \
diff --git a/libc/src/__support/annex_k/libc_constraint_hander.h b/libc/src/__support/annex_k/libc_constraint_handler.h
similarity index 93%
rename from libc/src/__support/annex_k/libc_constraint_hander.h
rename to libc/src/__support/annex_k/libc_constraint_handler.h
index a21b966133104..8e52f72d04277 100644
--- a/libc/src/__support/annex_k/libc_constraint_hander.h
+++ b/libc/src/__support/annex_k/libc_constraint_handler.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDER_H
 #define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDER_H
 
+#include "abort_handler_s.h"
 #include "hdr/types/constraint_handler_t.h"
-#include "src/__support/annex_k/abort_handler_s.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 32810b41b8866..9bc51c27d8d8a 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -204,14 +204,6 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.fdopen
 )
 
-add_entrypoint_object(
-  fopen_s
-  HDRS
-    fopen_s.h
-  DEPENDS
-    .generic.fopen_s
-)
-
 # These entrypoints have multiple potential implementations.
 add_stdio_entrypoint_object(feof)
 add_stdio_entrypoint_object(feof_unlocked)
@@ -226,6 +218,7 @@ add_stdio_entrypoint_object(fflush)
 add_stdio_entrypoint_object(clearerr)
 add_stdio_entrypoint_object(clearerr_unlocked)
 add_stdio_entrypoint_object(fopen)
+add_stdio_entrypoint_object(fopen_s)
 add_stdio_entrypoint_object(fclose)
 add_stdio_entrypoint_object(fread_unlocked)
 add_stdio_entrypoint_object(fread)
diff --git a/libc/src/stdlib/set_constraint_handler_s.cpp b/libc/src/stdlib/set_constraint_handler_s.cpp
index 5d215a58461be..7558b6b271e20 100644
--- a/libc/src/stdlib/set_constraint_handler_s.cpp
+++ b/libc/src/stdlib/set_constraint_handler_s.cpp
@@ -8,7 +8,7 @@
 
 #include "set_constraint_handler_s.h"
 #include "src/__support/annex_k/abort_handler_s.h"
-#include "src/__support/annex_k/libc_constraint_hander.h"
+#include "src/__support/annex_k/libc_constraint_handler.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE_DECL {

>From d9a7362eaa738966f73b7e256d43ba8c56213c1e Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 8 Aug 2025 06:25:58 +0300
Subject: [PATCH 3/5] make fullbuild only

---
 libc/config/linux/x86_64/entrypoints.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index b64e956fa3e96..e16d7152d8071 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -198,7 +198,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.qsort
     libc.src.stdlib.qsort_r
     libc.src.stdlib.rand
-    libc.src.stdlib.set_constraint_handler_s
     libc.src.stdlib.srand
     libc.src.stdlib.strfromd
     libc.src.stdlib.strfromf

>From 947b72375aa85c71100b3e3e76baa732352936bb Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 8 Aug 2025 06:56:29 +0300
Subject: [PATCH 4/5] remove calling public functions from internal code

---
 libc/src/__support/annex_k/CMakeLists.txt    |  4 +---
 libc/src/__support/annex_k/abort_handler_s.h | 17 +++++++++--------
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/libc/src/__support/annex_k/CMakeLists.txt b/libc/src/__support/annex_k/CMakeLists.txt
index 8ab4296f41fe5..6cbbe88bb5424 100644
--- a/libc/src/__support/annex_k/CMakeLists.txt
+++ b/libc/src/__support/annex_k/CMakeLists.txt
@@ -8,9 +8,7 @@ add_header_library(
     libc.src.__support.macros.config
     libc.src.__support.macros.attributes
     libc.src.__support.File.file
-    libc.src.stdio.fprintf
-    libc.src.stdio.fflush
-    libc.src.stdlib.abort
+    libc.src.__support.OSUtil.io
 )
 
 add_header_library(
diff --git a/libc/src/__support/annex_k/abort_handler_s.h b/libc/src/__support/annex_k/abort_handler_s.h
index 731f859c537ec..e496f44d60e26 100644
--- a/libc/src/__support/annex_k/abort_handler_s.h
+++ b/libc/src/__support/annex_k/abort_handler_s.h
@@ -14,9 +14,8 @@
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
-#include "src/stdio/fflush.h"
-#include "src/stdio/fprintf.h"
-#include "src/stdlib/abort.h"
+#include "src/__support/OSUtil/io.h"
+#include <stdlib.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
@@ -24,16 +23,18 @@ LIBC_INLINE static void abort_handler_s(const char *__restrict msg,
                                         [[maybe_unused]] void *__restrict ptr,
                                         errno_t error) {
   libc_errno = error;
-  fprintf(stderr, "abort_handler_s was called in response to a "
+  write_to_stderr("abort_handler_s was called in response to a "
                   "runtime-constraint violation.\n\n");
-  if (msg)
-    fprintf(stderr, "%s\n", msg);
-  fprintf(stderr,
+  if (msg) {
+    write_to_stderr(msg);
+    write_to_stderr("\n");
+  }
+
+  write_to_stderr(
           "\n\nNote to end users: This program was terminated as a result\
       of a bug present in the software. Please reach out to your  \
       software's vendor to get more help.\n");
 
-  fflush(stderr);
   abort();
 }
 

>From fad004489dd4b0b84db1395e54165c976f2d87a8 Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 8 Aug 2025 12:17:24 +0300
Subject: [PATCH 5/5] add default handlers

---
 libc/config/linux/x86_64/entrypoints.txt      |  2 +
 libc/include/llvm-libc-macros/CMakeLists.txt  |  6 +++
 .../include/llvm-libc-macros/annex-k-macros.h | 19 ++++++++
 libc/src/__support/annex_k/CMakeLists.txt     | 24 ----------
 .../annex_k/libc_constraint_handler.h         |  9 ++--
 libc/src/stdlib/CMakeLists.txt                | 44 ++++++++++++++++++-
 .../abort_handler_s.cpp}                      | 32 ++++++--------
 libc/src/stdlib/abort_handler_s.h             | 22 ++++++++++
 libc/src/stdlib/ignore_handler_s.cpp          | 16 +++++++
 .../annex_k => stdlib}/ignore_handler_s.h     | 13 +++---
 libc/src/stdlib/set_constraint_handler_s.cpp  |  2 +-
 11 files changed, 133 insertions(+), 56 deletions(-)
 create mode 100644 libc/include/llvm-libc-macros/annex-k-macros.h
 rename libc/src/{__support/annex_k/abort_handler_s.h => stdlib/abort_handler_s.cpp} (51%)
 create mode 100644 libc/src/stdlib/abort_handler_s.h
 create mode 100644 libc/src/stdlib/ignore_handler_s.cpp
 rename libc/src/{__support/annex_k => stdlib}/ignore_handler_s.h (53%)

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index e16d7152d8071..bf5493aa9d875 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1164,6 +1164,8 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.stdlib.getenv
     libc.src.stdlib.quick_exit
     libc.src.stdlib.set_constraint_handler_s
+    libc.src.stdlib.abort_handler_s
+    libc.src.stdlib.ignore_handler_s
 
     # signal.h entrypoints
     libc.src.signal.kill
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index 7aa549ddc75d9..30699c7e43ac8 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -31,6 +31,12 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
   add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
 endif()
 
+add_macro_header(
+  annex_k_macros
+  HDR
+    annex-k-macros.h
+)
+
 add_macro_header(
   assert_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/annex-k-macros.h b/libc/include/llvm-libc-macros/annex-k-macros.h
new file mode 100644
index 0000000000000..02c8dc60301a9
--- /dev/null
+++ b/libc/include/llvm-libc-macros/annex-k-macros.h
@@ -0,0 +1,19 @@
+//===-- Definition of macros to be used with Annex K functions ------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_INCLUDE_LLVM_LIBC_MACROS_ANNEX_K_MACROS_H
+#define LLVM_LIBC_INCLUDE_LLVM_LIBC_MACROS_ANNEX_K_MACROS_H
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L &&                \
+    defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ == 1
+
+#define LIBC_HAS_ANNEX_K
+
+#endif
+
+#endif // LLVM_LIBC_INCLUDE_LLVM_LIBC_MACROS_ANNEX_K_MACROS_H
diff --git a/libc/src/__support/annex_k/CMakeLists.txt b/libc/src/__support/annex_k/CMakeLists.txt
index 6cbbe88bb5424..646645696b5b4 100644
--- a/libc/src/__support/annex_k/CMakeLists.txt
+++ b/libc/src/__support/annex_k/CMakeLists.txt
@@ -1,27 +1,3 @@
-add_header_library(
-  abort_handler_s
-  HDRS
-    abort_handler_s.h
-  DEPENDS
-    libc.hdr.stdio_macros
-    libc.hdr.types.errno_t
-    libc.src.__support.macros.config
-    libc.src.__support.macros.attributes
-    libc.src.__support.File.file
-    libc.src.__support.OSUtil.io
-)
-
-add_header_library(
-  ignore_handler_s
-  HDRS
-    ignore_handler_s.h
-  DEPENDS
-    libc.hdr.types.errno_t
-    libc.src.__support.libc_errno
-    libc.src.__support.macros.config
-    libc.src.__support.macros.attributes
-)
-
 add_header_library(
   helper_macros
   HDRS
diff --git a/libc/src/__support/annex_k/libc_constraint_handler.h b/libc/src/__support/annex_k/libc_constraint_handler.h
index 8e52f72d04277..b1c97cc225e0f 100644
--- a/libc/src/__support/annex_k/libc_constraint_handler.h
+++ b/libc/src/__support/annex_k/libc_constraint_handler.h
@@ -6,11 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDER_H
-#define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDER_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDLER_H
+#define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDLER_H
 
-#include "abort_handler_s.h"
 #include "hdr/types/constraint_handler_t.h"
+#include "src/__support/common.h"
+#include "src/stdlib/abort_handler_s.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
@@ -19,4 +20,4 @@ LIBC_INLINE static constraint_handler_t libc_constraint_handler =
 
 }
 
-#endif // LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDER_H
+#endif // LLVM_LIBC_SRC___SUPPORT_ANNEX_K_LIBC_CONSTRAINT_HANDLER_H
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 0165c799b7aa8..5cfead6ae8020 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -660,7 +660,49 @@ add_entrypoint_object(
   HDRS
     set_constraint_handler_s.h
   DEPENDS
-    libc.src.__support.annex_k.abort_handler_s
+    .abort_handler_s
     libc.src.__support.annex_k.libc_constraint_handler
     libc.src.__support.macros.config
 )
+
+add_entrypoint_object(
+  abort_handler_s
+  SRCS
+    abort_handler_s.cpp
+  HDRS
+    abort_handler_s.h
+  DEPENDS
+    libc.hdr.stdio_macros
+    libc.hdr.types.errno_t
+    libc.src.__support.macros.config
+    libc.src.__support.macros.attributes
+    libc.src.__support.File.file
+)
+
+add_header_library(
+  libc_constraint_handler
+  HDRS
+    libc_constraint_handler.h
+  DEPENDS
+    .abort_handler_s
+    libc.hdr.types.constraint_handler_t
+)
+
+add_header_library(
+  annex_k_helper_macros
+  HDRS
+    annex_k_helper_macros.h
+)
+
+add_entrypoint_object(
+  ignore_handler_s
+  HDRS
+    ignore_handler_s.h
+  SRCS
+    ignore_handler_s.cpp
+  DEPENDS
+    libc.hdr.types.errno_t
+    libc.src.__support.libc_errno
+    libc.src.__support.macros.config
+    libc.src.__support.macros.attributes
+)
diff --git a/libc/src/__support/annex_k/abort_handler_s.h b/libc/src/stdlib/abort_handler_s.cpp
similarity index 51%
rename from libc/src/__support/annex_k/abort_handler_s.h
rename to libc/src/stdlib/abort_handler_s.cpp
index e496f44d60e26..7a82b2d073d25 100644
--- a/libc/src/__support/annex_k/abort_handler_s.h
+++ b/libc/src/stdlib/abort_handler_s.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation header for abort_handler_s ---------------*- C++ -*-===//
+//===-- Implementation for abort_handler_s ----------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,38 +6,32 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_ABORT_HANDLER_S_H
-#define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_ABORT_HANDLER_S_H
-
+#include "src/stdlib/abort_handler_s.h"
 #include "hdr/stdio_macros.h"
 #include "hdr/types/errno_t.h"
+#include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
-#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/OSUtil/io.h"
+#include <stdio.h>
 #include <stdlib.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
-LIBC_INLINE static void abort_handler_s(const char *__restrict msg,
-                                        [[maybe_unused]] void *__restrict ptr,
-                                        errno_t error) {
+LLVM_LIBC_FUNCTION(void, abort_handler_s,
+                   (const char *__restrict msg,
+                    [[maybe_unused]] void *__restrict ptr, errno_t error)) {
   libc_errno = error;
-  write_to_stderr("abort_handler_s was called in response to a "
+  fprintf(stderr, "abort_handler_s was called in response to a "
                   "runtime-constraint violation.\n\n");
-  if (msg) {
-    write_to_stderr(msg);
-    write_to_stderr("\n");
-  }
-
-  write_to_stderr(
+  if (msg)
+    fprintf(stderr, "%s\n", msg);
+  fprintf(stderr,
           "\n\nNote to end users: This program was terminated as a result\
       of a bug present in the software. Please reach out to your  \
       software's vendor to get more help.\n");
 
+  fflush(stderr);
+
   abort();
 }
 
 } // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_ANNEX_K_ABORT_HANDLER_S_H
diff --git a/libc/src/stdlib/abort_handler_s.h b/libc/src/stdlib/abort_handler_s.h
new file mode 100644
index 0000000000000..b97a081b036d2
--- /dev/null
+++ b/libc/src/stdlib/abort_handler_s.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for abort_handler_s ---------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_ABORT_HANDLER_S_H
+#define LLVM_LIBC_SRC_STDLIB_ABORT_HANDLER_S_H
+
+#include "hdr/types/errno_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+void abort_handler_s(const char *__restrict msg, void *__restrict ptr,
+                     errno_t error);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_ABORT_HANDLER_S_H
diff --git a/libc/src/stdlib/ignore_handler_s.cpp b/libc/src/stdlib/ignore_handler_s.cpp
new file mode 100644
index 0000000000000..172b1bcdb7b30
--- /dev/null
+++ b/libc/src/stdlib/ignore_handler_s.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation header for ignore_handler_s --------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/ignore_handler_s.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, ignore_handler_s,
+                   (const char *__restrict, void *__restrict, errno_t)) {}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/annex_k/ignore_handler_s.h b/libc/src/stdlib/ignore_handler_s.h
similarity index 53%
rename from libc/src/__support/annex_k/ignore_handler_s.h
rename to libc/src/stdlib/ignore_handler_s.h
index 7690776429945..07328d4be01ce 100644
--- a/libc/src/__support/annex_k/ignore_handler_s.h
+++ b/libc/src/stdlib/ignore_handler_s.h
@@ -6,18 +6,17 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC___SUPPORT_ANNEX_K_IGNORE_HANDLER_S_H
-#define LLVM_LIBC_SRC___SUPPORT_ANNEX_K_IGNORE_HANDLER_S_H
+#ifndef LLVM_LIBC_SRC_STDLIB_IGNORE_HANDLER_S_H
+#define LLVM_LIBC_SRC_STDLIB_IGNORE_HANDLER_S_H
 
 #include "hdr/types/errno_t.h"
-#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
+#include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
-LIBC_INLINE static void ignore_handler_s(const char *__restrict msg,
-                                         void *__restrict ptr, errno_t error) {}
+void ignore_handler_s(const char *__restrict msg, void *__restrict ptr,
+                      errno_t error);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC___SUPPORT_ANNEX_K_IGNORE_HANDLER_S_H
+#endif // LLVM_LIBC_SRC_STDLIB_IGNORE_HANDLER_S_H
diff --git a/libc/src/stdlib/set_constraint_handler_s.cpp b/libc/src/stdlib/set_constraint_handler_s.cpp
index 7558b6b271e20..020989ee862f9 100644
--- a/libc/src/stdlib/set_constraint_handler_s.cpp
+++ b/libc/src/stdlib/set_constraint_handler_s.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "set_constraint_handler_s.h"
-#include "src/__support/annex_k/abort_handler_s.h"
+#include "abort_handler_s.h"
 #include "src/__support/annex_k/libc_constraint_handler.h"
 #include "src/__support/common.h"
 



More information about the libc-commits mailing list