[libc-commits] [libc] [libc] Add sys/stat syscall wrappers (PR #195295)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Mon May 4 02:03:43 PDT 2026


https://github.com/kaladron updated https://github.com/llvm/llvm-project/pull/195295

>From 45818ea216a77197b45c3a54ccf428bc9cf38b9e Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Thu, 30 Apr 2026 15:07:45 +0100
Subject: [PATCH 1/2] [libc] Add sys/stat syscall wrappers

Added ErrorOr-returning syscall wrappers for chmod, fchmod, fchmodat,
mkdir, mkdirat, and statx in src/__support/OSUtil/linux/syscall_wrappers/.
Migrated the sys/stat Linux entrypoints to use them.

Added hdr/types/struct_stat.h proxy header. Updated stat, lstat, fstat
to use it, and kernel_statx to use the new statx wrapper.

Fixed fchmodat CMakeLists.txt to reference fchmodat.h (was fchmod.h).
Updated test dependencies to use hdr/sys_stat_macros.
---
 libc/hdr/types/CMakeLists.txt                 |  8 ++
 libc/hdr/types/struct_stat.h                  | 27 +++++++
 .../linux/syscall_wrappers/CMakeLists.txt     | 80 +++++++++++++++++++
 .../OSUtil/linux/syscall_wrappers/chmod.h     | 47 +++++++++++
 .../OSUtil/linux/syscall_wrappers/fchmod.h    | 37 +++++++++
 .../OSUtil/linux/syscall_wrappers/fchmodat.h  | 38 +++++++++
 .../OSUtil/linux/syscall_wrappers/mkdir.h     | 42 ++++++++++
 .../OSUtil/linux/syscall_wrappers/mkdirat.h   | 37 +++++++++
 .../OSUtil/linux/syscall_wrappers/statx.h     | 37 +++++++++
 libc/src/sys/stat/chmod.h                     |  2 +-
 libc/src/sys/stat/fchmod.h                    |  2 +-
 libc/src/sys/stat/fchmodat.h                  |  2 +-
 libc/src/sys/stat/fstat.h                     |  2 +-
 libc/src/sys/stat/linux/CMakeLists.txt        | 35 +++-----
 libc/src/sys/stat/linux/chmod.cpp             | 24 +-----
 libc/src/sys/stat/linux/fchmod.cpp            | 12 +--
 libc/src/sys/stat/linux/fchmodat.cpp          | 12 +--
 libc/src/sys/stat/linux/fstat.cpp             |  2 +-
 libc/src/sys/stat/linux/kernel_statx.h        | 13 ++-
 libc/src/sys/stat/linux/lstat.cpp             |  2 +-
 libc/src/sys/stat/linux/mkdir.cpp             | 21 +----
 libc/src/sys/stat/linux/mkdirat.cpp           | 16 +---
 libc/src/sys/stat/linux/stat.cpp              |  2 +-
 libc/src/sys/stat/lstat.h                     |  2 +-
 libc/src/sys/stat/mkdir.h                     |  2 +-
 libc/src/sys/stat/mkdirat.h                   |  2 +-
 libc/src/sys/stat/stat.h                      |  2 +-
 libc/test/src/stdio/CMakeLists.txt            |  2 +
 libc/test/src/stdio/remove_test.cpp           |  1 +
 libc/test/src/stdio/rename_test.cpp           |  2 +-
 libc/test/src/sys/stat/CMakeLists.txt         |  2 +-
 libc/test/src/sys/stat/mkdirat_test.cpp       |  1 +
 .../test/src/sys/statvfs/linux/CMakeLists.txt |  2 +
 .../src/sys/statvfs/linux/fstatvfs_test.cpp   |  1 +
 .../src/sys/statvfs/linux/statvfs_test.cpp    |  1 +
 libc/test/src/unistd/CMakeLists.txt           |  1 +
 libc/test/src/unistd/rmdir_test.cpp           |  1 +
 37 files changed, 415 insertions(+), 107 deletions(-)
 create mode 100644 libc/hdr/types/struct_stat.h
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/chmod.h
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/fchmod.h
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/mkdir.h
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/mkdirat.h
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/statx.h

diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index a3057397725bd..a511944547d8a 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -159,6 +159,14 @@ add_proxy_header_library(
     libc.include.llvm-libc-types.size_t
 )
 
+add_proxy_header_library(
+  struct_stat
+  HDRS
+    struct_stat.h
+  FULL_BUILD_DEPENDS
+    libc.include.llvm-libc-types.struct_stat
+)
+
 add_proxy_header_library(
   ssize_t
   HDRS
diff --git a/libc/hdr/types/struct_stat.h b/libc/hdr/types/struct_stat.h
new file mode 100644
index 0000000000000..74cf381b27f05
--- /dev/null
+++ b/libc/hdr/types/struct_stat.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Proxy header for struct stat.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_STAT_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_STAT_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_stat.h"
+
+#else // Overlay mode
+
+#include <sys/stat.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_STAT_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 2215d2cab2851..edfda18146bce 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -235,3 +235,83 @@ add_header_library(
     libc.hdr.errno_macros
     libc.include.sys_syscall
 )
+
+add_header_library(
+  statx
+  HDRS
+    statx.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.include.sys_syscall
+)
+
+add_header_library(
+  mkdir
+  HDRS
+    mkdir.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.fcntl_macros
+    libc.hdr.types.mode_t
+    libc.include.sys_syscall
+)
+
+add_header_library(
+  mkdirat
+  HDRS
+    mkdirat.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.types.mode_t
+    libc.include.sys_syscall
+)
+
+add_header_library(
+  chmod
+  HDRS
+    chmod.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.fcntl_macros
+    libc.hdr.types.mode_t
+    libc.include.sys_syscall
+)
+
+add_header_library(
+  fchmod
+  HDRS
+    fchmod.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.types.mode_t
+    libc.include.sys_syscall
+)
+
+add_header_library(
+  fchmodat
+  HDRS
+    fchmodat.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.types.mode_t
+    libc.include.sys_syscall
+)
+
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/chmod.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/chmod.h
new file mode 100644
index 0000000000000..69acf4c5cf1b3
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/chmod.h
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// ErrorOr-returning syscall wrapper for chmod.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHMOD_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHMOD_H
+
+#include "hdr/fcntl_macros.h"
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> chmod(const char *path, mode_t mode) {
+#ifdef SYS_chmod
+  int ret = syscall_impl<int>(SYS_chmod, path, mode);
+#elif defined(SYS_fchmodat)
+  int ret = syscall_impl<int>(SYS_fchmodat, AT_FDCWD, path, mode, 0);
+#elif defined(SYS_fchmodat2)
+  int ret = syscall_impl<int>(SYS_fchmodat2, AT_FDCWD, path, mode, 0,
+                              AT_SYMLINK_NOFOLLOW);
+#else
+#error "chmod, fchmodat and fchmodat2 syscalls not available."
+#endif
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHMOD_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/fchmod.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/fchmod.h
new file mode 100644
index 0000000000000..4760a821726e1
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/fchmod.h
@@ -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
+/// ErrorOr-returning syscall wrapper for fchmod.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHMOD_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHMOD_H
+
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> fchmod(int fd, mode_t mode) {
+  int ret = syscall_impl<int>(SYS_fchmod, fd, mode);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHMOD_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h
new file mode 100644
index 0000000000000..7b8ee1a079b99
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h
@@ -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
+/// ErrorOr-returning syscall wrapper for fchmodat.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHMODAT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHMODAT_H
+
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> fchmodat(int fd, const char *path, mode_t mode,
+                                  int flags) {
+  int ret = syscall_impl<int>(SYS_fchmodat, fd, path, mode, flags);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHMODAT_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/mkdir.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/mkdir.h
new file mode 100644
index 0000000000000..6d77894c36b6b
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/mkdir.h
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// ErrorOr-returning syscall wrapper for mkdir.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKDIR_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKDIR_H
+
+#include "hdr/fcntl_macros.h"
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> mkdir(const char *path, mode_t mode) {
+#ifdef SYS_mkdir
+  int ret = syscall_impl<int>(SYS_mkdir, path, mode);
+#else
+  int ret = syscall_impl<int>(SYS_mkdirat, AT_FDCWD, path, mode);
+#endif
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKDIR_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/mkdirat.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/mkdirat.h
new file mode 100644
index 0000000000000..70e67e3fb7809
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/mkdirat.h
@@ -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
+/// ErrorOr-returning syscall wrapper for mkdirat.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKDIRAT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKDIRAT_H
+
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> mkdirat(int dfd, const char *path, mode_t mode) {
+  int ret = syscall_impl<int>(SYS_mkdirat, dfd, path, mode);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKDIRAT_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/statx.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/statx.h
new file mode 100644
index 0000000000000..c65a74fc3ec08
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/statx.h
@@ -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
+/// ErrorOr-returning syscall wrapper for statx.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_STATX_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_STATX_H
+
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> statx(int dirfd, const char *path, int flags,
+                               unsigned int mask, void *statxbuf) {
+  int ret = syscall_impl<int>(SYS_statx, dirfd, path, flags, mask, statxbuf);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_STATX_H
diff --git a/libc/src/sys/stat/chmod.h b/libc/src/sys/stat/chmod.h
index a05407a40978f..0db42000794f2 100644
--- a/libc/src/sys/stat/chmod.h
+++ b/libc/src/sys/stat/chmod.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_STAT_CHMOD_H
 #define LLVM_LIBC_SRC_SYS_STAT_CHMOD_H
 
+#include "hdr/types/mode_t.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/fchmod.h b/libc/src/sys/stat/fchmod.h
index 470ce3e3a03a2..ba99d4d5e0469 100644
--- a/libc/src/sys/stat/fchmod.h
+++ b/libc/src/sys/stat/fchmod.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_STAT_FCHMOD_H
 #define LLVM_LIBC_SRC_SYS_STAT_FCHMOD_H
 
+#include "hdr/types/mode_t.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/fchmodat.h b/libc/src/sys/stat/fchmodat.h
index e4500f505bfda..848a2f04f9d7f 100644
--- a/libc/src/sys/stat/fchmodat.h
+++ b/libc/src/sys/stat/fchmodat.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_STAT_FCHMODAT_H
 #define LLVM_LIBC_SRC_SYS_STAT_FCHMODAT_H
 
+#include "hdr/types/mode_t.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/fstat.h b/libc/src/sys/stat/fstat.h
index a3ec9e45384c9..1e2eef5dbf47f 100644
--- a/libc/src/sys/stat/fstat.h
+++ b/libc/src/sys/stat/fstat.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_STAT_FSTAT_H
 #define LLVM_LIBC_SRC_SYS_STAT_FSTAT_H
 
+#include "hdr/types/struct_stat.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/linux/CMakeLists.txt b/libc/src/sys/stat/linux/CMakeLists.txt
index 4fd8fe98890de..20ebd7716f75b 100644
--- a/libc/src/sys/stat/linux/CMakeLists.txt
+++ b/libc/src/sys/stat/linux/CMakeLists.txt
@@ -7,9 +7,7 @@ add_entrypoint_object(
   DEPENDS
     libc.hdr.types.mode_t
     libc.hdr.fcntl_macros
-    libc.include.sys_stat
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.chmod
     libc.src.errno.errno
 )
 
@@ -21,9 +19,7 @@ add_entrypoint_object(
     ../fchmod.h
   DEPENDS
     libc.hdr.types.mode_t
-    libc.include.sys_stat
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.fchmod
     libc.src.errno.errno
 )
 
@@ -32,11 +28,10 @@ add_entrypoint_object(
   SRCS
     fchmodat.cpp
   HDRS
-    ../fchmod.h
+    ../fchmodat.h
   DEPENDS
-    libc.include.sys_stat
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.hdr.types.mode_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.fchmodat
     libc.src.errno.errno
 )
 
@@ -49,9 +44,7 @@ add_entrypoint_object(
   DEPENDS
     libc.hdr.types.mode_t
     libc.hdr.fcntl_macros
-    libc.include.sys_stat
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.mkdir
     libc.src.errno.errno
 )
 
@@ -62,9 +55,8 @@ add_entrypoint_object(
   HDRS
     ../mkdirat.h
   DEPENDS
-    libc.include.sys_stat
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.hdr.types.mode_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.mkdirat
     libc.src.errno.errno
 )
 
@@ -74,9 +66,8 @@ add_header_library(
     kernel_statx.h
   DEPENDS
     libc.hdr.stdint_proxy
-    libc.include.sys_stat
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.hdr.types.struct_stat
+    libc.src.__support.OSUtil.linux.syscall_wrappers.statx
     libc.src.__support.common
 )
 
@@ -89,7 +80,7 @@ add_entrypoint_object(
   DEPENDS
     .kernel_statx
     libc.hdr.fcntl_macros
-    libc.include.sys_stat
+    libc.hdr.types.struct_stat
     libc.src.errno.errno
 )
 
@@ -102,7 +93,7 @@ add_entrypoint_object(
   DEPENDS
     .kernel_statx
     libc.hdr.fcntl_macros
-    libc.include.sys_stat
+    libc.hdr.types.struct_stat
     libc.src.errno.errno
 )
 
@@ -115,7 +106,7 @@ add_entrypoint_object(
   DEPENDS
     .kernel_statx
     libc.hdr.fcntl_macros
-    libc.include.sys_stat
+    libc.hdr.types.struct_stat
     libc.src.errno.errno
 )
 
diff --git a/libc/src/sys/stat/linux/chmod.cpp b/libc/src/sys/stat/linux/chmod.cpp
index 2bd0788ec1dfd..bd9b12fea50d3 100644
--- a/libc/src/sys/stat/linux/chmod.cpp
+++ b/libc/src/sys/stat/linux/chmod.cpp
@@ -8,33 +8,17 @@
 
 #include "src/sys/stat/chmod.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/chmod.h"
 #include "src/__support/common.h"
-
-#include "hdr/fcntl_macros.h"
-#include "hdr/types/mode_t.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, chmod, (const char *path, mode_t mode)) {
-#ifdef SYS_chmod
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_chmod, path, mode);
-#elif defined(SYS_fchmodat)
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat, AT_FDCWD, path, mode, 0);
-#elif defined(SYS_fchmodat2)
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat2, AT_FDCWD, path,
-                                              mode, 0, AT_SYMLINK_NOFOLLOW);
-#else
-#error "chmod, fchmodat and fchmodat2 syscalls not available."
-#endif
-
-  if (ret < 0) {
-    libc_errno = -ret;
+  auto result = linux_syscalls::chmod(path, mode);
+  if (!result) {
+    libc_errno = result.error();
     return -1;
   }
   return 0;
diff --git a/libc/src/sys/stat/linux/fchmod.cpp b/libc/src/sys/stat/linux/fchmod.cpp
index 3dadfdd1d943c..aa59b59a50cd7 100644
--- a/libc/src/sys/stat/linux/fchmod.cpp
+++ b/libc/src/sys/stat/linux/fchmod.cpp
@@ -8,21 +8,17 @@
 
 #include "src/sys/stat/fchmod.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/fchmod.h"
 #include "src/__support/common.h"
-
-#include "hdr/types/mode_t.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, fchmod, (int fd, mode_t mode)) {
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmod, fd, mode);
-  if (ret < 0) {
-    libc_errno = -ret;
+  auto result = linux_syscalls::fchmod(fd, mode);
+  if (!result) {
+    libc_errno = result.error();
     return -1;
   }
   return 0;
diff --git a/libc/src/sys/stat/linux/fchmodat.cpp b/libc/src/sys/stat/linux/fchmodat.cpp
index add2192a558a4..38e02b5d61617 100644
--- a/libc/src/sys/stat/linux/fchmodat.cpp
+++ b/libc/src/sys/stat/linux/fchmodat.cpp
@@ -8,22 +8,18 @@
 
 #include "src/sys/stat/fchmodat.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, fchmodat,
                    (int dirfd, const char *path, mode_t mode, int flags)) {
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat, dirfd, path, mode, flags);
-  if (ret < 0) {
-    libc_errno = -ret;
+  auto result = linux_syscalls::fchmodat(dirfd, path, mode, flags);
+  if (!result) {
+    libc_errno = result.error();
     return -1;
   }
   return 0;
diff --git a/libc/src/sys/stat/linux/fstat.cpp b/libc/src/sys/stat/linux/fstat.cpp
index dea002c5e12a5..65fe5a8f755f9 100644
--- a/libc/src/sys/stat/linux/fstat.cpp
+++ b/libc/src/sys/stat/linux/fstat.cpp
@@ -14,7 +14,7 @@
 #include "src/__support/common.h"
 
 #include "hdr/fcntl_macros.h"
-#include <sys/stat.h>
+#include "hdr/types/struct_stat.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/linux/kernel_statx.h b/libc/src/sys/stat/linux/kernel_statx.h
index 455ab17a2fb97..97d06c6f8075e 100644
--- a/libc/src/sys/stat/linux/kernel_statx.h
+++ b/libc/src/sys/stat/linux/kernel_statx.h
@@ -10,12 +10,11 @@
 #define LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H
 
 #include "hdr/stdint_proxy.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/statx.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 
-#include <sys/stat.h>
-#include <sys/syscall.h> // For syscall numbers.
+#include "hdr/types/struct_stat.h"
 
 // It is safe to include this kernel header as it is designed to be
 // included from user programs without causing any name pollution.
@@ -74,10 +73,10 @@ LIBC_INLINE int statx(int dirfd, const char *__restrict path, int flags,
                       struct stat *__restrict statbuf) {
   // We make a statx syscall and copy out the result into the |statbuf|.
   ::statx_buf xbuf;
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_statx, dirfd, path, flags,
-                                              ::STATX_BASIC_STATS_MASK, &xbuf);
-  if (ret < 0)
-    return -ret;
+  auto result = linux_syscalls::statx(dirfd, path, flags,
+                                      ::STATX_BASIC_STATS_MASK, &xbuf);
+  if (!result)
+    return result.error();
 
   statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor);
   statbuf->st_ino = static_cast<decltype(statbuf->st_ino)>(xbuf.stx_ino);
diff --git a/libc/src/sys/stat/linux/lstat.cpp b/libc/src/sys/stat/linux/lstat.cpp
index 5601dd5d78a98..05826d167a7bc 100644
--- a/libc/src/sys/stat/linux/lstat.cpp
+++ b/libc/src/sys/stat/linux/lstat.cpp
@@ -15,7 +15,7 @@
 #include "src/__support/common.h"
 
 #include "hdr/fcntl_macros.h"
-#include <sys/stat.h>
+#include "hdr/types/struct_stat.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/linux/mkdir.cpp b/libc/src/sys/stat/linux/mkdir.cpp
index 0829ff4f94322..4d6197ff25efb 100644
--- a/libc/src/sys/stat/linux/mkdir.cpp
+++ b/libc/src/sys/stat/linux/mkdir.cpp
@@ -8,30 +8,17 @@
 
 #include "src/sys/stat/mkdir.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/mkdir.h"
 #include "src/__support/common.h"
-
-#include "hdr/fcntl_macros.h"
-#include "hdr/types/mode_t.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, mkdir, (const char *path, mode_t mode)) {
-#ifdef SYS_mkdir
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_mkdir, path, mode);
-#elif defined(SYS_mkdirat)
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_mkdirat, AT_FDCWD, path, mode);
-#else
-#error "mkdir and mkdirat syscalls not available."
-#endif
-
-  if (ret < 0) {
-    libc_errno = -ret;
+  auto result = linux_syscalls::mkdir(path, mode);
+  if (!result) {
+    libc_errno = result.error();
     return -1;
   }
   return 0;
diff --git a/libc/src/sys/stat/linux/mkdirat.cpp b/libc/src/sys/stat/linux/mkdirat.cpp
index 8f4194dc32752..623a94b1345d8 100644
--- a/libc/src/sys/stat/linux/mkdirat.cpp
+++ b/libc/src/sys/stat/linux/mkdirat.cpp
@@ -8,25 +8,17 @@
 
 #include "src/sys/stat/mkdirat.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/mkdirat.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, mkdirat, (int dfd, const char *path, mode_t mode)) {
-#ifdef SYS_mkdirat
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_mkdirat, dfd, path, mode);
-#else
-#error "mkdirat syscall not available."
-#endif
-
-  if (ret < 0) {
-    libc_errno = -ret;
+  auto result = linux_syscalls::mkdirat(dfd, path, mode);
+  if (!result) {
+    libc_errno = result.error();
     return -1;
   }
   return 0;
diff --git a/libc/src/sys/stat/linux/stat.cpp b/libc/src/sys/stat/linux/stat.cpp
index 5553eaf00be2a..eeaf8787e460a 100644
--- a/libc/src/sys/stat/linux/stat.cpp
+++ b/libc/src/sys/stat/linux/stat.cpp
@@ -14,7 +14,7 @@
 #include "src/__support/common.h"
 
 #include "hdr/fcntl_macros.h"
-#include <sys/stat.h>
+#include "hdr/types/struct_stat.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/lstat.h b/libc/src/sys/stat/lstat.h
index a94fc69969ab9..535f217dea4dd 100644
--- a/libc/src/sys/stat/lstat.h
+++ b/libc/src/sys/stat/lstat.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_STAT_LSTAT_H
 #define LLVM_LIBC_SRC_SYS_STAT_LSTAT_H
 
+#include "hdr/types/struct_stat.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/mkdir.h b/libc/src/sys/stat/mkdir.h
index 2d990bacd564e..f53734e679643 100644
--- a/libc/src/sys/stat/mkdir.h
+++ b/libc/src/sys/stat/mkdir.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_STAT_MKDIR_H
 #define LLVM_LIBC_SRC_SYS_STAT_MKDIR_H
 
+#include "hdr/types/mode_t.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/mkdirat.h b/libc/src/sys/stat/mkdirat.h
index e26cf5b58b8b1..8c130dfd3522d 100644
--- a/libc/src/sys/stat/mkdirat.h
+++ b/libc/src/sys/stat/mkdirat.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_STAT_MKDIRAT_H
 #define LLVM_LIBC_SRC_SYS_STAT_MKDIRAT_H
 
+#include "hdr/types/mode_t.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/stat/stat.h b/libc/src/sys/stat/stat.h
index 8ec3e9b1aa9e0..3ec49bee69f0e 100644
--- a/libc/src/sys/stat/stat.h
+++ b/libc/src/sys/stat/stat.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_STAT_STAT_H
 #define LLVM_LIBC_SRC_SYS_STAT_STAT_H
 
+#include "hdr/types/struct_stat.h"
 #include "src/__support/macros/config.h"
-#include <sys/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
index 038ac9766b80b..f5eb5c81f90e1 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -465,6 +465,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
     SRCS
       remove_test.cpp
     DEPENDS
+      libc.hdr.sys_stat_macros
       libc.include.unistd
       libc.src.errno.errno
       libc.src.fcntl.open
@@ -482,6 +483,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
     SRCS
       rename_test.cpp
     DEPENDS
+      libc.hdr.sys_stat_macros
       libc.src.errno.errno
       libc.src.fcntl.open
       libc.src.stdio.rename
diff --git a/libc/test/src/stdio/remove_test.cpp b/libc/test/src/stdio/remove_test.cpp
index 20d166f0acb2f..dc783851a02ef 100644
--- a/libc/test/src/stdio/remove_test.cpp
+++ b/libc/test/src/stdio/remove_test.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "hdr/sys_stat_macros.h"
 #include "src/fcntl/open.h"
 #include "src/stdio/remove.h"
 #include "src/sys/stat/mkdirat.h"
diff --git a/libc/test/src/stdio/rename_test.cpp b/libc/test/src/stdio/rename_test.cpp
index af957e0fcbf79..433a2613b70b1 100644
--- a/libc/test/src/stdio/rename_test.cpp
+++ b/libc/test/src/stdio/rename_test.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "include/llvm-libc-macros/linux/sys-stat-macros.h"
+#include "hdr/sys_stat_macros.h"
 #include "include/llvm-libc-macros/linux/unistd-macros.h"
 #include "src/fcntl/open.h"
 #include "src/stdio/rename.h"
diff --git a/libc/test/src/sys/stat/CMakeLists.txt b/libc/test/src/sys/stat/CMakeLists.txt
index 85fc7589bd81e..7786baf1cf20b 100644
--- a/libc/test/src/sys/stat/CMakeLists.txt
+++ b/libc/test/src/sys/stat/CMakeLists.txt
@@ -64,7 +64,7 @@ add_libc_unittest(
     mkdirat_test.cpp
   DEPENDS
     libc.hdr.fcntl_macros
-    libc.include.sys_stat
+    libc.hdr.sys_stat_macros
     libc.src.errno.errno
     libc.src.sys.stat.mkdirat
     libc.src.unistd.rmdir
diff --git a/libc/test/src/sys/stat/mkdirat_test.cpp b/libc/test/src/sys/stat/mkdirat_test.cpp
index fd32a441e264d..c733a6638473e 100644
--- a/libc/test/src/sys/stat/mkdirat_test.cpp
+++ b/libc/test/src/sys/stat/mkdirat_test.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "hdr/sys_stat_macros.h"
 #include "src/sys/stat/mkdirat.h"
 #include "src/unistd/rmdir.h"
 #include "test/UnitTest/ErrnoCheckingTest.h"
diff --git a/libc/test/src/sys/statvfs/linux/CMakeLists.txt b/libc/test/src/sys/statvfs/linux/CMakeLists.txt
index 37c67fdb5fe19..545baceae58c0 100644
--- a/libc/test/src/sys/statvfs/linux/CMakeLists.txt
+++ b/libc/test/src/sys/statvfs/linux/CMakeLists.txt
@@ -7,6 +7,7 @@ add_libc_unittest(
   SRCS
     statvfs_test.cpp
   DEPENDS
+    libc.hdr.sys_stat_macros
     libc.src.errno.errno
     libc.src.sys.statvfs.statvfs
     libc.src.sys.stat.mkdirat
@@ -22,6 +23,7 @@ add_libc_unittest(
   SRCS
     fstatvfs_test.cpp
   DEPENDS
+    libc.hdr.sys_stat_macros
     libc.src.errno.errno
     libc.src.sys.statvfs.fstatvfs
     libc.src.sys.stat.mkdirat
diff --git a/libc/test/src/sys/statvfs/linux/fstatvfs_test.cpp b/libc/test/src/sys/statvfs/linux/fstatvfs_test.cpp
index ba0ee4f09109e..acf5b199aff29 100644
--- a/libc/test/src/sys/statvfs/linux/fstatvfs_test.cpp
+++ b/libc/test/src/sys/statvfs/linux/fstatvfs_test.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 #include "src/fcntl/open.h"
diff --git a/libc/test/src/sys/statvfs/linux/statvfs_test.cpp b/libc/test/src/sys/statvfs/linux/statvfs_test.cpp
index 327dec07a1b79..df3ddca3c379e 100644
--- a/libc/test/src/sys/statvfs/linux/statvfs_test.cpp
+++ b/libc/test/src/sys/statvfs/linux/statvfs_test.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 #include "src/sys/stat/mkdirat.h"
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 4f748746706a3..89d111a8ff54e 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -314,6 +314,7 @@ add_libc_unittest(
     rmdir_test.cpp
   DEPENDS
     libc.hdr.fcntl_macros
+    libc.hdr.sys_stat_macros
     libc.src.errno.errno
     libc.src.sys.stat.mkdir
     libc.src.unistd.rmdir
diff --git a/libc/test/src/unistd/rmdir_test.cpp b/libc/test/src/unistd/rmdir_test.cpp
index 860cf1ce87ddb..699d38c72e1f3 100644
--- a/libc/test/src/unistd/rmdir_test.cpp
+++ b/libc/test/src/unistd/rmdir_test.cpp
@@ -13,6 +13,7 @@
 #include "test/UnitTest/Test.h"
 
 #include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
 
 using LlvmLibcRmdirTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 

>From f5bc238d1a2c89516860682d5e7058e49cdd878d Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Mon, 4 May 2026 10:03:23 +0100
Subject: [PATCH 2/2] [libc] Move errno handling into kernel_statx

kernel_statx now sets libc_errno and returns -1 on failure,
matching the convention used by the other stat entrypoints.
Simplified stat, lstat, and fstat to forward the return value
directly.
---
 libc/src/sys/stat/linux/CMakeLists.txt | 4 +---
 libc/src/sys/stat/linux/fstat.cpp      | 8 +-------
 libc/src/sys/stat/linux/kernel_statx.h | 7 +++++--
 libc/src/sys/stat/linux/lstat.cpp      | 9 +--------
 libc/src/sys/stat/linux/stat.cpp       | 8 +-------
 5 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/libc/src/sys/stat/linux/CMakeLists.txt b/libc/src/sys/stat/linux/CMakeLists.txt
index 20ebd7716f75b..005ebfc81bef2 100644
--- a/libc/src/sys/stat/linux/CMakeLists.txt
+++ b/libc/src/sys/stat/linux/CMakeLists.txt
@@ -69,6 +69,7 @@ add_header_library(
     libc.hdr.types.struct_stat
     libc.src.__support.OSUtil.linux.syscall_wrappers.statx
     libc.src.__support.common
+    libc.src.__support.libc_errno
 )
 
 add_entrypoint_object(
@@ -81,7 +82,6 @@ add_entrypoint_object(
     .kernel_statx
     libc.hdr.fcntl_macros
     libc.hdr.types.struct_stat
-    libc.src.errno.errno
 )
 
 add_entrypoint_object(
@@ -94,7 +94,6 @@ add_entrypoint_object(
     .kernel_statx
     libc.hdr.fcntl_macros
     libc.hdr.types.struct_stat
-    libc.src.errno.errno
 )
 
 add_entrypoint_object(
@@ -107,7 +106,6 @@ add_entrypoint_object(
     .kernel_statx
     libc.hdr.fcntl_macros
     libc.hdr.types.struct_stat
-    libc.src.errno.errno
 )
 
 add_entrypoint_object(
diff --git a/libc/src/sys/stat/linux/fstat.cpp b/libc/src/sys/stat/linux/fstat.cpp
index 65fe5a8f755f9..07e8b00a5fbb3 100644
--- a/libc/src/sys/stat/linux/fstat.cpp
+++ b/libc/src/sys/stat/linux/fstat.cpp
@@ -8,7 +8,6 @@
 
 #include "src/sys/stat/fstat.h"
 #include "kernel_statx.h"
-#include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
 #include "src/__support/common.h"
@@ -19,12 +18,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, fstat, (int fd, struct stat *statbuf)) {
-  int err = statx(fd, "", AT_EMPTY_PATH, statbuf);
-  if (err != 0) {
-    libc_errno = err;
-    return -1;
-  }
-  return 0;
+  return statx(fd, "", AT_EMPTY_PATH, statbuf);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/stat/linux/kernel_statx.h b/libc/src/sys/stat/linux/kernel_statx.h
index 97d06c6f8075e..7c2160992102f 100644
--- a/libc/src/sys/stat/linux/kernel_statx.h
+++ b/libc/src/sys/stat/linux/kernel_statx.h
@@ -12,6 +12,7 @@
 #include "hdr/stdint_proxy.h"
 #include "src/__support/OSUtil/linux/syscall_wrappers/statx.h"
 #include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
 #include "hdr/types/struct_stat.h"
@@ -75,8 +76,10 @@ LIBC_INLINE int statx(int dirfd, const char *__restrict path, int flags,
   ::statx_buf xbuf;
   auto result = linux_syscalls::statx(dirfd, path, flags,
                                       ::STATX_BASIC_STATS_MASK, &xbuf);
-  if (!result)
-    return result.error();
+  if (!result) {
+    libc_errno = result.error();
+    return -1;
+  }
 
   statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor);
   statbuf->st_ino = static_cast<decltype(statbuf->st_ino)>(xbuf.stx_ino);
diff --git a/libc/src/sys/stat/linux/lstat.cpp b/libc/src/sys/stat/linux/lstat.cpp
index 05826d167a7bc..dd917d47d1491 100644
--- a/libc/src/sys/stat/linux/lstat.cpp
+++ b/libc/src/sys/stat/linux/lstat.cpp
@@ -8,10 +8,8 @@
 
 #include "src/sys/stat/lstat.h"
 #include "kernel_statx.h"
-#include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 
 #include "hdr/fcntl_macros.h"
@@ -22,12 +20,7 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(int, lstat,
                    (const char *__restrict path,
                     struct stat *__restrict statbuf)) {
-  int err = statx(AT_FDCWD, path, AT_SYMLINK_NOFOLLOW, statbuf);
-  if (err != 0) {
-    libc_errno = err;
-    return -1;
-  }
-  return 0;
+  return statx(AT_FDCWD, path, AT_SYMLINK_NOFOLLOW, statbuf);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/stat/linux/stat.cpp b/libc/src/sys/stat/linux/stat.cpp
index eeaf8787e460a..8261752a699d1 100644
--- a/libc/src/sys/stat/linux/stat.cpp
+++ b/libc/src/sys/stat/linux/stat.cpp
@@ -8,7 +8,6 @@
 
 #include "src/sys/stat/stat.h"
 #include "kernel_statx.h"
-#include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
 #include "src/__support/common.h"
@@ -21,12 +20,7 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(int, stat,
                    (const char *__restrict path,
                     struct stat *__restrict statbuf)) {
-  int err = statx(AT_FDCWD, path, 0, statbuf);
-  if (err != 0) {
-    libc_errno = err;
-    return -1;
-  }
-  return 0;
+  return statx(AT_FDCWD, path, 0, statbuf);
 }
 
 } // namespace LIBC_NAMESPACE_DECL



More information about the libc-commits mailing list