[libc-commits] [libc] [libc] Implement BSD extensions in <err.h> (PR #199055)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Thu May 21 08:24:04 PDT 2026
https://github.com/kaladron updated https://github.com/llvm/llvm-project/pull/199055
>From 6a123e4c476a8e61f1c7826e52b83b9ef91f9bd6 Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Thu, 21 May 2026 15:27:59 +0100
Subject: [PATCH] [libc] Implement BSD extensions in <err.h>
Implemented the BSD-extension functions defined in <err.h>:
- err, errx, verr, verrx
- warn, warnx, vwarn, vwarnx
Added an internal reporting helper in src/__support/Err. The err
family functions call internal::exit directly to satisfy [[noreturn]]
requirements. Enabled these entrypoints for aarch64, riscv, and x86_64.
Assisted-by: Automated tooling, human reviewed.
---
libc/config/linux/aarch64/entrypoints.txt | 10 ++
libc/config/linux/riscv/entrypoints.txt | 10 ++
libc/config/linux/x86_64/entrypoints.txt | 10 ++
libc/include/CMakeLists.txt | 8 ++
libc/include/err.yaml | 67 ++++++++++++
libc/src/CMakeLists.txt | 1 +
libc/src/__support/CMakeLists.txt | 1 +
libc/src/__support/Err/CMakeLists.txt | 15 +++
libc/src/__support/Err/error_reporting.cpp | 76 ++++++++++++++
libc/src/__support/Err/error_reporting.h | 28 +++++
libc/src/err/CMakeLists.txt | 115 +++++++++++++++++++++
libc/src/err/err.cpp | 36 +++++++
libc/src/err/err.h | 25 +++++
libc/src/err/errx.cpp | 36 +++++++
libc/src/err/errx.h | 25 +++++
libc/src/err/verr.cpp | 33 ++++++
libc/src/err/verr.h | 26 +++++
libc/src/err/verrx.cpp | 33 ++++++
libc/src/err/verrx.h | 26 +++++
libc/src/err/vwarn.cpp | 31 ++++++
libc/src/err/vwarn.h | 26 +++++
libc/src/err/vwarnx.cpp | 31 ++++++
libc/src/err/vwarnx.h | 26 +++++
libc/src/err/warn.cpp | 34 ++++++
libc/src/err/warn.h | 25 +++++
libc/src/err/warnx.cpp | 34 ++++++
libc/src/err/warnx.h | 25 +++++
libc/test/src/CMakeLists.txt | 1 +
libc/test/src/err/CMakeLists.txt | 21 ++++
libc/test/src/err/err_test.cpp | 89 ++++++++++++++++
30 files changed, 924 insertions(+)
create mode 100644 libc/include/err.yaml
create mode 100644 libc/src/__support/Err/CMakeLists.txt
create mode 100644 libc/src/__support/Err/error_reporting.cpp
create mode 100644 libc/src/__support/Err/error_reporting.h
create mode 100644 libc/src/err/CMakeLists.txt
create mode 100644 libc/src/err/err.cpp
create mode 100644 libc/src/err/err.h
create mode 100644 libc/src/err/errx.cpp
create mode 100644 libc/src/err/errx.h
create mode 100644 libc/src/err/verr.cpp
create mode 100644 libc/src/err/verr.h
create mode 100644 libc/src/err/verrx.cpp
create mode 100644 libc/src/err/verrx.h
create mode 100644 libc/src/err/vwarn.cpp
create mode 100644 libc/src/err/vwarn.h
create mode 100644 libc/src/err/vwarnx.cpp
create mode 100644 libc/src/err/vwarnx.h
create mode 100644 libc/src/err/warn.cpp
create mode 100644 libc/src/err/warn.h
create mode 100644 libc/src/err/warnx.cpp
create mode 100644 libc/src/err/warnx.h
create mode 100644 libc/test/src/err/CMakeLists.txt
create mode 100644 libc/test/src/err/err_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 07d4ad38a01e2..181ef10c4d666 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -23,6 +23,16 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.dlfcn.dlopen
libc.src.dlfcn.dlsym
+ # err.h entrypoints
+ libc.src.err.err
+ libc.src.err.verr
+ libc.src.err.errx
+ libc.src.err.verrx
+ libc.src.err.warn
+ libc.src.err.vwarn
+ libc.src.err.warnx
+ libc.src.err.vwarnx
+
# errno.h entrypoints
libc.src.errno.errno
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index a92a32f3ff14f..dae24cd3170b9 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -23,6 +23,16 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.dlfcn.dlopen
libc.src.dlfcn.dlsym
+ # err.h entrypoints
+ libc.src.err.err
+ libc.src.err.verr
+ libc.src.err.errx
+ libc.src.err.verrx
+ libc.src.err.warn
+ libc.src.err.vwarn
+ libc.src.err.warnx
+ libc.src.err.vwarnx
+
# errno.h entrypoints
libc.src.errno.errno
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 054b99b06be82..b62455571ed73 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -32,6 +32,16 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.dlfcn.dlopen
libc.src.dlfcn.dlsym
+ # err.h entrypoints
+ libc.src.err.err
+ libc.src.err.verr
+ libc.src.err.errx
+ libc.src.err.verrx
+ libc.src.err.warn
+ libc.src.err.vwarn
+ libc.src.err.warnx
+ libc.src.err.vwarnx
+
# errno.h entrypoints
libc.src.errno.errno
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 6a02241b7d6a2..7142edc192d7d 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -82,6 +82,14 @@ add_header_macro(
.llvm_libc_common_h
)
+add_header_macro(
+ err
+ ../libc/include/err.yaml
+ err.h
+ DEPENDS
+ .llvm_libc_common_h
+)
+
add_header_macro(
features
../libc/include/features.yaml
diff --git a/libc/include/err.yaml b/libc/include/err.yaml
new file mode 100644
index 0000000000000..753a49ae99e33
--- /dev/null
+++ b/libc/include/err.yaml
@@ -0,0 +1,67 @@
+header: err.h
+standards:
+ - bsd
+macros: []
+types:
+ - type_name: va_list
+functions:
+ - name: err
+ standards:
+ - bsd
+ return_type: void
+ arguments:
+ - type: int
+ - type: const char *
+ - type: '...'
+ - name: verr
+ standards:
+ - bsd
+ return_type: void
+ arguments:
+ - type: int
+ - type: const char *
+ - type: va_list
+ - name: errx
+ standards:
+ - bsd
+ return_type: void
+ arguments:
+ - type: int
+ - type: const char *
+ - type: '...'
+ - name: verrx
+ standards:
+ - bsd
+ return_type: void
+ arguments:
+ - type: int
+ - type: const char *
+ - type: va_list
+ - name: warn
+ standards:
+ - bsd
+ return_type: void
+ arguments:
+ - type: const char *
+ - type: '...'
+ - name: vwarn
+ standards:
+ - bsd
+ return_type: void
+ arguments:
+ - type: const char *
+ - type: va_list
+ - name: warnx
+ standards:
+ - bsd
+ return_type: void
+ arguments:
+ - type: const char *
+ - type: '...'
+ - name: vwarnx
+ standards:
+ - bsd
+ return_type: void
+ arguments:
+ - type: const char *
+ - type: va_list
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 56fb121ecda75..e4b97083d3ec3 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -5,6 +5,7 @@ add_subdirectory(complex)
add_subdirectory(ctype)
add_subdirectory(dlfcn)
add_subdirectory(errno)
+add_subdirectory(err)
add_subdirectory(fenv)
add_subdirectory(inttypes)
add_subdirectory(link)
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index ada489046ef9e..fc314a1a905a7 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -473,3 +473,4 @@ add_subdirectory(math)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
add_subdirectory(mathvec)
endif()
+add_subdirectory(Err)
diff --git a/libc/src/__support/Err/CMakeLists.txt b/libc/src/__support/Err/CMakeLists.txt
new file mode 100644
index 0000000000000..813d767e6124c
--- /dev/null
+++ b/libc/src/__support/Err/CMakeLists.txt
@@ -0,0 +1,15 @@
+add_object_library(
+ error_reporting
+ HDRS
+ error_reporting.h
+ SRCS
+ error_reporting.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.src.__support.arg_list
+ libc.src.__support.libc_errno
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.StringUtil.error_to_string
+ libc.src.stdio.printf_core.printf_main
+ libc.src.stdio.printf_core.writer
+)
diff --git a/libc/src/__support/Err/error_reporting.cpp b/libc/src/__support/Err/error_reporting.cpp
new file mode 100644
index 0000000000000..facce91dd2701
--- /dev/null
+++ b/libc/src/__support/Err/error_reporting.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of internal error reporting helpers.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/Err/error_reporting.h"
+
+#include "hdr/errno_macros.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/StringUtil/error_to_string.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/printf_core/printf_main.h"
+#include "src/stdio/printf_core/writer.h"
+
+#ifdef __linux__
+extern "C" char *program_invocation_short_name;
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+namespace err_reporting {
+
+namespace {
+
+void write_to_stderr(cpp::string_view msg) {
+ LIBC_NAMESPACE::write_to_stderr(msg);
+}
+
+} // namespace
+
+void report(bool show_err, const char *fmt, internal::ArgList &args) {
+ int saved_errno = libc_errno;
+
+ const char *progname = "libllvmlibc";
+ // TODO: Use a proper way to get progname if available.
+#ifdef __linux__
+ progname = program_invocation_short_name;
+#endif
+
+ write_to_stderr(progname);
+ write_to_stderr(": ");
+
+ if (fmt != nullptr) {
+ char buffer[1024];
+ printf_core::FlushingBuffer wb(
+ buffer, sizeof(buffer),
+ [](cpp::string_view str, [[maybe_unused]] void *raw_stream) -> int {
+ LIBC_NAMESPACE::write_to_stderr(str);
+ return static_cast<int>(str.size());
+ },
+ nullptr);
+ printf_core::Writer writer(wb);
+ printf_core::printf_main(&writer, fmt, args);
+ wb.flush_to_stream();
+ if (show_err)
+ write_to_stderr(": ");
+ }
+
+ if (show_err)
+ write_to_stderr(get_error_string(saved_errno));
+
+ write_to_stderr("\n");
+}
+
+} // namespace err_reporting
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/Err/error_reporting.h b/libc/src/__support/Err/error_reporting.h
new file mode 100644
index 0000000000000..d23052c34495c
--- /dev/null
+++ b/libc/src/__support/Err/error_reporting.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation header for internal error reporting.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_ERR_ERROR_REPORTING_H
+#define LLVM_LIBC_SRC___SUPPORT_ERR_ERROR_REPORTING_H
+
+#include "src/__support/arg_list.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace err_reporting {
+
+void report(bool show_err, const char *fmt, internal::ArgList &args);
+
+} // namespace err_reporting
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_ERR_ERROR_REPORTING_H
diff --git a/libc/src/err/CMakeLists.txt b/libc/src/err/CMakeLists.txt
new file mode 100644
index 0000000000000..902d680b248d5
--- /dev/null
+++ b/libc/src/err/CMakeLists.txt
@@ -0,0 +1,115 @@
+add_entrypoint_object(
+ err
+ SRCS
+ err.cpp
+ HDRS
+ err.h
+ DEPENDS
+ libc.src.__support.Err.error_reporting
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.arg_list
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+)
+
+add_entrypoint_object(
+ verr
+ SRCS
+ verr.cpp
+ HDRS
+ verr.h
+ DEPENDS
+ libc.src.__support.Err.error_reporting
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.arg_list
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+)
+
+add_entrypoint_object(
+ errx
+ SRCS
+ errx.cpp
+ HDRS
+ errx.h
+ DEPENDS
+ libc.src.__support.Err.error_reporting
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.arg_list
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+)
+
+add_entrypoint_object(
+ verrx
+ SRCS
+ verrx.cpp
+ HDRS
+ verrx.h
+ DEPENDS
+ libc.src.__support.Err.error_reporting
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.arg_list
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+)
+
+add_entrypoint_object(
+ warn
+ SRCS
+ warn.cpp
+ HDRS
+ warn.h
+ DEPENDS
+ libc.src.__support.Err.error_reporting
+ libc.src.__support.arg_list
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+)
+
+add_entrypoint_object(
+ vwarn
+ SRCS
+ vwarn.cpp
+ HDRS
+ vwarn.h
+ DEPENDS
+ libc.src.__support.Err.error_reporting
+ libc.src.__support.arg_list
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+)
+
+add_entrypoint_object(
+ warnx
+ SRCS
+ warnx.cpp
+ HDRS
+ warnx.h
+ DEPENDS
+ libc.src.__support.Err.error_reporting
+ libc.src.__support.arg_list
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+)
+
+add_entrypoint_object(
+ vwarnx
+ SRCS
+ vwarnx.cpp
+ HDRS
+ vwarnx.h
+ DEPENDS
+ libc.src.__support.Err.error_reporting
+ libc.src.__support.arg_list
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+)
diff --git a/libc/src/err/err.cpp b/libc/src/err/err.cpp
new file mode 100644
index 0000000000000..aa8c67fddf094
--- /dev/null
+++ b/libc/src/err/err.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of err.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/err/err.h"
+#include "src/__support/Err/error_reporting.h"
+#include "src/__support/OSUtil/exit.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, err, (int eval, const char *fmt, ...)) {
+ LIBC_CRASH_ON_NULLPTR(fmt);
+ va_list args;
+ va_start(args, fmt);
+ internal::ArgList arg_list(args);
+ err_reporting::report(true, fmt, arg_list);
+ va_end(args);
+ internal::exit(eval);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/err/err.h b/libc/src/err/err.h
new file mode 100644
index 0000000000000..1ab2f284fa742
--- /dev/null
+++ b/libc/src/err/err.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation header for err.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERR_ERR_H
+#define LLVM_LIBC_SRC_ERR_ERR_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+[[noreturn]] void err(int eval, const char *fmt, ...);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_ERR_ERR_H
diff --git a/libc/src/err/errx.cpp b/libc/src/err/errx.cpp
new file mode 100644
index 0000000000000..b906bf88977fd
--- /dev/null
+++ b/libc/src/err/errx.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of errx.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/err/errx.h"
+#include "src/__support/Err/error_reporting.h"
+#include "src/__support/OSUtil/exit.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, errx, (int eval, const char *fmt, ...)) {
+ LIBC_CRASH_ON_NULLPTR(fmt);
+ va_list args;
+ va_start(args, fmt);
+ internal::ArgList arg_list(args);
+ err_reporting::report(false, fmt, arg_list);
+ va_end(args);
+ internal::exit(eval);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/err/errx.h b/libc/src/err/errx.h
new file mode 100644
index 0000000000000..a2885e715b85f
--- /dev/null
+++ b/libc/src/err/errx.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation header for errx.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERR_ERRX_H
+#define LLVM_LIBC_SRC_ERR_ERRX_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+[[noreturn]] void errx(int eval, const char *fmt, ...);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_ERR_ERRX_H
diff --git a/libc/src/err/verr.cpp b/libc/src/err/verr.cpp
new file mode 100644
index 0000000000000..89caebf76b091
--- /dev/null
+++ b/libc/src/err/verr.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of verr.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/err/verr.h"
+#include "src/__support/Err/error_reporting.h"
+#include "src/__support/OSUtil/exit.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, verr, (int eval, const char *fmt, va_list args)) {
+ LIBC_CRASH_ON_NULLPTR(fmt);
+ internal::ArgList arg_list(args);
+ err_reporting::report(true, fmt, arg_list);
+ internal::exit(eval);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/err/verr.h b/libc/src/err/verr.h
new file mode 100644
index 0000000000000..24054c5a17fef
--- /dev/null
+++ b/libc/src/err/verr.h
@@ -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
+/// Implementation header for verr.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERR_VERR_H
+#define LLVM_LIBC_SRC_ERR_VERR_H
+
+#include "src/__support/macros/config.h"
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+[[noreturn]] void verr(int eval, const char *fmt, va_list args);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_ERR_VERR_H
diff --git a/libc/src/err/verrx.cpp b/libc/src/err/verrx.cpp
new file mode 100644
index 0000000000000..fceb46781f173
--- /dev/null
+++ b/libc/src/err/verrx.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of verrx.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/err/verrx.h"
+#include "src/__support/Err/error_reporting.h"
+#include "src/__support/OSUtil/exit.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, verrx, (int eval, const char *fmt, va_list args)) {
+ LIBC_CRASH_ON_NULLPTR(fmt);
+ internal::ArgList arg_list(args);
+ err_reporting::report(false, fmt, arg_list);
+ internal::exit(eval);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/err/verrx.h b/libc/src/err/verrx.h
new file mode 100644
index 0000000000000..c12b067b9fdde
--- /dev/null
+++ b/libc/src/err/verrx.h
@@ -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
+/// Implementation header for verrx.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERR_VERRX_H
+#define LLVM_LIBC_SRC_ERR_VERRX_H
+
+#include "src/__support/macros/config.h"
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+[[noreturn]] void verrx(int eval, const char *fmt, va_list args);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_ERR_VERRX_H
diff --git a/libc/src/err/vwarn.cpp b/libc/src/err/vwarn.cpp
new file mode 100644
index 0000000000000..fe2d14f920666
--- /dev/null
+++ b/libc/src/err/vwarn.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of vwarn.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/err/vwarn.h"
+#include "src/__support/Err/error_reporting.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, vwarn, (const char *fmt, va_list args)) {
+ LIBC_CRASH_ON_NULLPTR(fmt);
+ internal::ArgList arg_list(args);
+ err_reporting::report(true, fmt, arg_list);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/err/vwarn.h b/libc/src/err/vwarn.h
new file mode 100644
index 0000000000000..71cd21e2e40ff
--- /dev/null
+++ b/libc/src/err/vwarn.h
@@ -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
+/// Implementation header for vwarn.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERR_VWARN_H
+#define LLVM_LIBC_SRC_ERR_VWARN_H
+
+#include "src/__support/macros/config.h"
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+void vwarn(const char *fmt, va_list args);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_ERR_VWARN_H
diff --git a/libc/src/err/vwarnx.cpp b/libc/src/err/vwarnx.cpp
new file mode 100644
index 0000000000000..cc390fe9b07cb
--- /dev/null
+++ b/libc/src/err/vwarnx.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of vwarnx.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/err/vwarnx.h"
+#include "src/__support/Err/error_reporting.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, vwarnx, (const char *fmt, va_list args)) {
+ LIBC_CRASH_ON_NULLPTR(fmt);
+ internal::ArgList arg_list(args);
+ err_reporting::report(false, fmt, arg_list);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/err/vwarnx.h b/libc/src/err/vwarnx.h
new file mode 100644
index 0000000000000..a1a871a96f37d
--- /dev/null
+++ b/libc/src/err/vwarnx.h
@@ -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
+/// Implementation header for vwarnx.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERR_VWARNX_H
+#define LLVM_LIBC_SRC_ERR_VWARNX_H
+
+#include "src/__support/macros/config.h"
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+void vwarnx(const char *fmt, va_list args);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_ERR_VWARNX_H
diff --git a/libc/src/err/warn.cpp b/libc/src/err/warn.cpp
new file mode 100644
index 0000000000000..f9ba23304ce02
--- /dev/null
+++ b/libc/src/err/warn.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of warn.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/err/warn.h"
+#include "src/__support/Err/error_reporting.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, warn, (const char *fmt, ...)) {
+ LIBC_CRASH_ON_NULLPTR(fmt);
+ va_list args;
+ va_start(args, fmt);
+ internal::ArgList arg_list(args);
+ err_reporting::report(true, fmt, arg_list);
+ va_end(args);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/err/warn.h b/libc/src/err/warn.h
new file mode 100644
index 0000000000000..01385cbfbe205
--- /dev/null
+++ b/libc/src/err/warn.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation header for warn.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERR_WARN_H
+#define LLVM_LIBC_SRC_ERR_WARN_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+void warn(const char *fmt, ...);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_ERR_WARN_H
diff --git a/libc/src/err/warnx.cpp b/libc/src/err/warnx.cpp
new file mode 100644
index 0000000000000..e3346e039b8eb
--- /dev/null
+++ b/libc/src/err/warnx.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of warnx.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/err/warnx.h"
+#include "src/__support/Err/error_reporting.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, warnx, (const char *fmt, ...)) {
+ LIBC_CRASH_ON_NULLPTR(fmt);
+ va_list args;
+ va_start(args, fmt);
+ internal::ArgList arg_list(args);
+ err_reporting::report(false, fmt, arg_list);
+ va_end(args);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/err/warnx.h b/libc/src/err/warnx.h
new file mode 100644
index 0000000000000..692175c8c5d5d
--- /dev/null
+++ b/libc/src/err/warnx.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation header for warnx.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERR_WARNX_H
+#define LLVM_LIBC_SRC_ERR_WARNX_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+void warnx(const char *fmt, ...);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_ERR_WARNX_H
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 7ee978f209388..07a6e163b238a 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -62,6 +62,7 @@ add_subdirectory(arpa)
add_subdirectory(complex)
add_subdirectory(ctype)
add_subdirectory(errno)
+add_subdirectory(err)
add_subdirectory(fenv)
add_subdirectory(link)
add_subdirectory(math)
diff --git a/libc/test/src/err/CMakeLists.txt b/libc/test/src/err/CMakeLists.txt
new file mode 100644
index 0000000000000..84c780da377c9
--- /dev/null
+++ b/libc/test/src/err/CMakeLists.txt
@@ -0,0 +1,21 @@
+add_custom_target(libc_err_unittests)
+
+add_libc_test(
+ err_test
+ UNIT_TEST_ONLY
+ SUITE
+ libc_err_unittests
+ SRCS
+ err_test.cpp
+ DEPENDS
+ libc.src.err.err
+ libc.src.err.errx
+ libc.src.err.verr
+ libc.src.err.verrx
+ libc.src.err.warn
+ libc.src.err.warnx
+ libc.src.err.vwarn
+ libc.src.err.vwarnx
+ libc.src.__support.libc_errno
+ libc.src.__support.common
+)
diff --git a/libc/test/src/err/err_test.cpp b/libc/test/src/err/err_test.cpp
new file mode 100644
index 0000000000000..f084c5c8e28af
--- /dev/null
+++ b/libc/test/src/err/err_test.cpp
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Unit tests for err family functions.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/err/err.h"
+#include "src/err/errx.h"
+#include "src/err/verr.h"
+#include "src/err/verrx.h"
+#include "src/err/vwarn.h"
+#include "src/err/vwarnx.h"
+#include "src/err/warn.h"
+#include "src/err/warnx.h"
+#include "test/UnitTest/Test.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE {
+
+namespace {
+void call_verr(int eval, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ verr(eval, fmt, args);
+ va_end(args);
+}
+
+void call_verrx(int eval, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ verrx(eval, fmt, args);
+ va_end(args);
+}
+
+void call_vwarn(const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vwarn(fmt, args);
+ va_end(args);
+}
+
+void call_vwarnx(const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vwarnx(fmt, args);
+ va_end(args);
+}
+} // namespace
+
+TEST(LlvmLibcErrTest, ErrExitCode) {
+ libc_errno = 0;
+ EXPECT_EXITS([] { err(1, "test err"); }, 1);
+ libc_errno = 2; // ENOENT
+ EXPECT_EXITS([] { err(127, "test err %d", 42); }, 127);
+}
+
+TEST(LlvmLibcErrTest, ErrxExitCode) {
+ EXPECT_EXITS([] { errx(2, "test errx"); }, 2);
+}
+
+TEST(LlvmLibcErrTest, VerrExitCode) {
+ libc_errno = 0;
+ EXPECT_EXITS([] { call_verr(1, "test verr"); }, 1);
+}
+
+TEST(LlvmLibcErrTest, VerrxExitCode) {
+ EXPECT_EXITS([] { call_verrx(2, "test verrx"); }, 2);
+}
+
+TEST(LlvmLibcErrTest, WarnNoExit) {
+ libc_errno = 0;
+ warn("test warn");
+ libc_errno = 1;
+ warnx("test warnx");
+ call_vwarn("test vwarn");
+ call_vwarnx("test vwarnx");
+}
+
+} // namespace LIBC_NAMESPACE
More information about the libc-commits
mailing list