[libc-commits] [libc] 1b38e21 - Syscall migrations of stdio and unistd (#196403)

via libc-commits libc-commits at lists.llvm.org
Fri May 8 05:23:34 PDT 2026


Author: Jeff Bailey
Date: 2026-05-08T13:23:28+01:00
New Revision: 1b38e21077dc469b0c67360440e4d19710ef053e

URL: https://github.com/llvm/llvm-project/commit/1b38e21077dc469b0c67360440e4d19710ef053e
DIFF: https://github.com/llvm/llvm-project/commit/1b38e21077dc469b0c67360440e4d19710ef053e.diff

LOG: Syscall migrations of stdio and unistd (#196403)

Added ErrorOr-returning syscall wrappers for access, chdir, dup, dup2,
dup3, faccessat, fchdir, fsync, lseek, readlink, readlinkat, rename,
rmdir, and unlinkat.

Migrated the Linux entrypoint implementations in src/unistd/linux/ and
src/stdio/linux/rename.cpp to use them.

Replaced internal::lseekimpl() with linux_syscalls::lseek() in the
File infrastructure and deleted the now-unused lseekImpl.h.

Assisted-by: Automated tooling, human reviewed.

Added: 
    libc/src/__support/OSUtil/linux/syscall_wrappers/access.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/chdir.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/dup.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/dup2.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/dup3.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/faccessat.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/fchdir.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/fsync.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/lseek.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/readlinkat.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/rename.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/rmdir.h
    libc/src/__support/OSUtil/linux/syscall_wrappers/unlinkat.h

Modified: 
    libc/src/__support/File/linux/CMakeLists.txt
    libc/src/__support/File/linux/file.cpp
    libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
    libc/src/stdio/linux/CMakeLists.txt
    libc/src/stdio/linux/rename.cpp
    libc/src/unistd/linux/CMakeLists.txt
    libc/src/unistd/linux/access.cpp
    libc/src/unistd/linux/chdir.cpp
    libc/src/unistd/linux/dup.cpp
    libc/src/unistd/linux/dup2.cpp
    libc/src/unistd/linux/dup3.cpp
    libc/src/unistd/linux/faccessat.cpp
    libc/src/unistd/linux/fchdir.cpp
    libc/src/unistd/linux/fsync.cpp
    libc/src/unistd/linux/lseek.cpp
    libc/src/unistd/linux/readlink.cpp
    libc/src/unistd/linux/readlinkat.cpp
    libc/src/unistd/linux/rmdir.cpp
    libc/src/unistd/linux/unlink.cpp
    libc/src/unistd/linux/unlinkat.cpp

Removed: 
    libc/src/__support/File/linux/lseekImpl.h


################################################################################
diff  --git a/libc/src/__support/File/linux/CMakeLists.txt b/libc/src/__support/File/linux/CMakeLists.txt
index c046dd4066900..2becb385e44d9 100644
--- a/libc/src/__support/File/linux/CMakeLists.txt
+++ b/libc/src/__support/File/linux/CMakeLists.txt
@@ -5,17 +5,15 @@ add_object_library(
     file.cpp
   HDRS
     file.h
-    lseekImpl.h
   DEPENDS
     libc.hdr.fcntl_macros
     libc.hdr.stdio_macros
-    libc.hdr.stdint_proxy
-    libc.hdr.types.off_t
     libc.hdr.types.FILE
     libc.include.sys_syscall
     libc.include.sys_stat
     libc.src.__support.CPP.new
     libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.lseek
     libc.src.__support.error_or
     libc.src.__support.File.file
     libc.src.errno.errno

diff  --git a/libc/src/__support/File/linux/file.cpp b/libc/src/__support/File/linux/file.cpp
index 13065300e5a34..10a6f2a97dc41 100644
--- a/libc/src/__support/File/linux/file.cpp
+++ b/libc/src/__support/File/linux/file.cpp
@@ -12,8 +12,8 @@
 #include "hdr/types/off_t.h"
 #include "src/__support/CPP/new.h"
 #include "src/__support/File/file.h"
-#include "src/__support/File/linux/lseekImpl.h"
 #include "src/__support/OSUtil/fcntl.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/lseek.h"
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/alloc-checker.h"
 #include "src/__support/libc_errno.h" // For error macros
@@ -47,10 +47,7 @@ FileIOResult linux_file_read(File *f, void *buf, size_t size) {
 
 ErrorOr<off_t> linux_file_seek(File *f, off_t offset, int whence) {
   auto *lf = reinterpret_cast<LinuxFile *>(f);
-  auto result = internal::lseekimpl(lf->get_fd(), offset, whence);
-  if (!result.has_value())
-    return result.error();
-  return result.value();
+  return linux_syscalls::lseek(lf->get_fd(), offset, whence);
 }
 
 int linux_file_close(File *f) {

diff  --git a/libc/src/__support/File/linux/lseekImpl.h b/libc/src/__support/File/linux/lseekImpl.h
deleted file mode 100644
index 47df99ae84b90..0000000000000
--- a/libc/src/__support/File/linux/lseekImpl.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- Linux implementation of lseek -------------------------------------===//
-//
-// 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_FILE_LINUX_LSEEKIMPL_H
-#define LLVM_LIBC_SRC___SUPPORT_FILE_LINUX_LSEEKIMPL_H
-
-#include "hdr/stdint_proxy.h" // For uint64_t.
-#include "hdr/types/off_t.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
-#include "src/__support/common.h"
-#include "src/__support/error_or.h"
-#include "src/__support/libc_errno.h"
-#include "src/__support/macros/config.h"
-
-#include <sys/syscall.h> // For syscall numbers.
-
-namespace LIBC_NAMESPACE_DECL {
-namespace internal {
-
-LIBC_INLINE ErrorOr<off_t> lseekimpl(int fd, off_t offset, int whence) {
-  off_t result;
-#ifdef SYS_lseek
-  result = LIBC_NAMESPACE::syscall_impl<off_t>(SYS_lseek, fd, offset, whence);
-  if (result < 0)
-    return Error(-static_cast<int>(result));
-#elif defined(SYS_llseek) || defined(SYS__llseek)
-  static_assert(sizeof(size_t) == 4, "size_t must be 32 bits.");
-#ifdef SYS_llseek
-  constexpr long LLSEEK_SYSCALL_NO = SYS_llseek;
-#elif defined(SYS__llseek)
-  constexpr long LLSEEK_SYSCALL_NO = SYS__llseek;
-#endif
-  off_t offset_64 = offset;
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(
-      LLSEEK_SYSCALL_NO, fd, offset_64 >> 32, offset_64, &result, whence);
-  if (ret < 0)
-    return Error(-ret);
-#else
-#error "lseek, llseek and _llseek syscalls not available."
-#endif
-  return result;
-}
-
-} // namespace internal
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_FILE_LINUX_LSEEKIMPL_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 6418d6f83dbfa..bbe76fece3bdd 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -365,3 +365,181 @@ add_header_library(
     libc.hdr.fcntl_macros
     libc.include.sys_syscall
 )
+
+add_header_library(
+  unlinkat
+  HDRS
+    unlinkat.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(
+  rmdir
+  HDRS
+    rmdir.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.include.sys_syscall
+)
+
+add_header_library(
+  chdir
+  HDRS
+    chdir.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(
+  fchdir
+  HDRS
+    fchdir.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(
+  fsync
+  HDRS
+    fsync.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(
+  dup
+  HDRS
+    dup.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(
+  dup2
+  HDRS
+    dup2.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.include.sys_syscall
+)
+
+add_header_library(
+  dup3
+  HDRS
+    dup3.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(
+  access
+  HDRS
+    access.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.include.sys_syscall
+)
+
+add_header_library(
+  faccessat
+  HDRS
+    faccessat.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(
+  readlink
+  HDRS
+    readlink.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.ssize_t
+    libc.include.sys_syscall
+)
+
+add_header_library(
+  readlinkat
+  HDRS
+    readlinkat.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.types.ssize_t
+    libc.include.sys_syscall
+)
+
+add_header_library(
+  rename
+  HDRS
+    rename.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.include.sys_syscall
+)
+
+add_header_library(
+  lseek
+  HDRS
+    lseek.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.stdint_proxy
+    libc.hdr.types.off_t
+    libc.include.sys_syscall
+)

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/access.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/access.h
new file mode 100644
index 0000000000000..3f3a3bd343901
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/access.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Syscall wrapper for access.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ACCESS_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ACCESS_H
+
+#include "hdr/fcntl_macros.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> access(const char *path, int mode) {
+#ifdef SYS_access
+  int ret = syscall_impl<int>(SYS_access, path, mode);
+#elif defined(SYS_faccessat)
+  int ret = syscall_impl<int>(SYS_faccessat, AT_FDCWD, path, mode, 0);
+#else
+#error "access and faccessat 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_ACCESS_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/chdir.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/chdir.h
new file mode 100644
index 0000000000000..3bd87ca0f488f
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/chdir.h
@@ -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
+/// Syscall wrapper for chdir.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHDIR_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHDIR_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> chdir(const char *path) {
+  int ret = syscall_impl<int>(SYS_chdir, path);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHDIR_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/dup.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/dup.h
new file mode 100644
index 0000000000000..3d54b684bd66e
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/dup.h
@@ -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
+/// Syscall wrapper for dup.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_DUP_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_DUP_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> dup(int fd) {
+  int ret = syscall_impl<int>(SYS_dup, fd);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_DUP_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/dup2.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/dup2.h
new file mode 100644
index 0000000000000..49f37134bd5f5
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/dup2.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Syscall wrapper for dup2.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_DUP2_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_DUP2_H
+
+#include "hdr/fcntl_macros.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> dup2(int oldfd, int newfd) {
+#ifdef SYS_dup2
+  int ret = syscall_impl<int>(SYS_dup2, oldfd, newfd);
+#elif defined(SYS_dup3)
+  if (oldfd == newfd) {
+#if defined(SYS_fcntl)
+    int ret = syscall_impl<int>(SYS_fcntl, oldfd, F_GETFD);
+#elif defined(SYS_fcntl64)
+    int ret = syscall_impl<int>(SYS_fcntl64, oldfd, F_GETFD);
+#else
+#error "SYS_fcntl and SYS_fcntl64 syscalls not available."
+#endif
+    if (ret >= 0)
+      return oldfd;
+    return Error(-ret);
+  }
+  int ret = syscall_impl<int>(SYS_dup3, oldfd, newfd, 0);
+#else
+#error "dup2 and dup3 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_DUP2_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/dup3.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/dup3.h
new file mode 100644
index 0000000000000..3be0ad4526e90
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/dup3.h
@@ -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
+/// Syscall wrapper for dup3.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_DUP3_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_DUP3_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> dup3(int oldfd, int newfd, int flags) {
+  int ret = syscall_impl<int>(SYS_dup3, oldfd, newfd, flags);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_DUP3_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/faccessat.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/faccessat.h
new file mode 100644
index 0000000000000..83fd7e617fb8a
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/faccessat.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Syscall wrapper for faccessat.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FACCESSAT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FACCESSAT_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> faccessat(int dfd, const char *path, int mode,
+                                   int flags) {
+#ifdef SYS_faccessat2
+  int ret = syscall_impl<int>(SYS_faccessat2, dfd, path, mode, flags);
+#elif defined(SYS_faccessat)
+  int ret = syscall_impl<int>(SYS_faccessat, dfd, path, mode, flags);
+#else
+#error "faccessat2 and faccessat 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_FACCESSAT_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/fchdir.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/fchdir.h
new file mode 100644
index 0000000000000..2830bb763a86a
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/fchdir.h
@@ -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
+/// Syscall wrapper for fchdir.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHDIR_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHDIR_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> fchdir(int fd) {
+  int ret = syscall_impl<int>(SYS_fchdir, fd);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHDIR_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/fsync.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/fsync.h
new file mode 100644
index 0000000000000..1ebbca23f3019
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/fsync.h
@@ -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
+/// Syscall wrapper for fsync.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FSYNC_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FSYNC_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> fsync(int fd) {
+  int ret = syscall_impl<int>(SYS_fsync, fd);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FSYNC_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/lseek.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/lseek.h
new file mode 100644
index 0000000000000..861a1174d367f
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/lseek.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Syscall wrapper for lseek.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LSEEK_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LSEEK_H
+
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/off_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<off_t> lseek(int fd, off_t offset, int whence) {
+  off_t result;
+#ifdef SYS_lseek
+  result = syscall_impl<off_t>(SYS_lseek, fd, offset, whence);
+  if (result < 0)
+    return Error(-static_cast<int>(result));
+#elif defined(SYS_llseek) || defined(SYS__llseek)
+#ifdef SYS_llseek
+  constexpr long LLSEEK_SYSCALL_NO = SYS_llseek;
+#elif defined(SYS__llseek)
+  constexpr long LLSEEK_SYSCALL_NO = SYS__llseek;
+#endif
+  uint64_t offset_64 = static_cast<uint64_t>(offset);
+  int ret = syscall_impl<int>(LLSEEK_SYSCALL_NO, fd,
+                              static_cast<long>(offset_64 >> 32),
+                              static_cast<long>(offset_64), &result, whence);
+  if (ret < 0)
+    return Error(-ret);
+#else
+#error "lseek, llseek and _llseek syscalls not available."
+#endif
+  return result;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LSEEK_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
new file mode 100644
index 0000000000000..7c6a0c8db0fee
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Syscall wrapper for readlink.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINK_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINK_H
+
+#include "hdr/fcntl_macros.h"
+#include "hdr/types/ssize_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<ssize_t> readlink(const char *path, char *buf,
+                                      size_t bufsiz) {
+#ifdef SYS_readlink
+  ssize_t ret = syscall_impl<ssize_t>(SYS_readlink, path, buf, bufsiz);
+#elif defined(SYS_readlinkat)
+  ssize_t ret =
+      syscall_impl<ssize_t>(SYS_readlinkat, AT_FDCWD, path, buf, bufsiz);
+#else
+#error "readlink and readlinkat syscalls not available."
+#endif
+  if (ret < 0)
+    return Error(-static_cast<int>(ret));
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINK_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/readlinkat.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/readlinkat.h
new file mode 100644
index 0000000000000..d65573c9d8aee
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/readlinkat.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
+/// Syscall wrapper for readlinkat.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINKAT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINKAT_H
+
+#include "hdr/types/ssize_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<ssize_t> readlinkat(int dfd, const char *path, char *buf,
+                                        size_t bufsiz) {
+  ssize_t ret = syscall_impl<ssize_t>(SYS_readlinkat, dfd, path, buf, bufsiz);
+  if (ret < 0)
+    return Error(-static_cast<int>(ret));
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINKAT_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/rename.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/rename.h
new file mode 100644
index 0000000000000..ec0be35b27ab8
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/rename.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
+/// Syscall wrapper for rename.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RENAME_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RENAME_H
+
+#include "hdr/fcntl_macros.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> rename(const char *oldpath, const char *newpath) {
+#ifdef SYS_renameat2
+  int ret =
+      syscall_impl<int>(SYS_renameat2, AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
+#elif defined(SYS_renameat)
+  int ret =
+      syscall_impl<int>(SYS_renameat, AT_FDCWD, oldpath, AT_FDCWD, newpath);
+#elif defined(SYS_rename)
+  int ret = syscall_impl<int>(SYS_rename, oldpath, newpath);
+#else
+#error "rename, renameat and renameat2 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_RENAME_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/rmdir.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/rmdir.h
new file mode 100644
index 0000000000000..cf8f03ce9fdfb
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/rmdir.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Syscall wrapper for rmdir.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RMDIR_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RMDIR_H
+
+#include "hdr/fcntl_macros.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> rmdir(const char *path) {
+#ifdef SYS_rmdir
+  int ret = syscall_impl<int>(SYS_rmdir, path);
+#elif defined(SYS_unlinkat)
+  int ret = syscall_impl<int>(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#else
+#error "rmdir and unlinkat 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_RMDIR_H

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/unlinkat.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/unlinkat.h
new file mode 100644
index 0000000000000..ffba729333fbd
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/unlinkat.h
@@ -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
+/// Syscall wrapper for unlinkat.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UNLINKAT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UNLINKAT_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> unlinkat(int dfd, const char *path, int flags) {
+  int ret = syscall_impl<int>(SYS_unlinkat, dfd, path, flags);
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UNLINKAT_H

diff  --git a/libc/src/stdio/linux/CMakeLists.txt b/libc/src/stdio/linux/CMakeLists.txt
index 5b7bd84f1ceea..1552060c52550 100644
--- a/libc/src/stdio/linux/CMakeLists.txt
+++ b/libc/src/stdio/linux/CMakeLists.txt
@@ -19,10 +19,8 @@ add_entrypoint_object(
   HDRS
     ../rename.h
   DEPENDS
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.rename
     libc.src.errno.errno
-    libc.hdr.fcntl_macros
 )
 
 add_entrypoint_object(

diff  --git a/libc/src/stdio/linux/rename.cpp b/libc/src/stdio/linux/rename.cpp
index 426c8698e557d..7f8515b705386 100644
--- a/libc/src/stdio/linux/rename.cpp
+++ b/libc/src/stdio/linux/rename.cpp
@@ -7,23 +7,20 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/stdio/rename.h"
-#include "hdr/fcntl_macros.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/rename.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, rename, (const char *oldpath, const char *newpath)) {
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_renameat2, AT_FDCWD, oldpath,
-                                              AT_FDCWD, newpath, 0);
-
-  if (ret >= 0)
-    return 0;
-  libc_errno = -ret;
-  return -1;
+  auto result = linux_syscalls::rename(oldpath, newpath);
+  if (!result) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return 0;
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index f979ba0669872..8153196b0a21c 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -5,10 +5,7 @@ add_entrypoint_object(
   HDRS
     ../access.h
   DEPENDS
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.access
     libc.src.errno.errno
 )
 
@@ -19,9 +16,7 @@ add_entrypoint_object(
   HDRS
     ../chdir.h
   DEPENDS
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.chdir
     libc.src.errno.errno
 )
 
@@ -59,10 +54,7 @@ add_entrypoint_object(
   HDRS
     ../dup.h
   DEPENDS
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.dup
     libc.src.errno.errno
 )
 
@@ -73,10 +65,7 @@ add_entrypoint_object(
   HDRS
     ../dup2.h
   DEPENDS
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.dup2
     libc.src.errno.errno
 )
 
@@ -87,10 +76,7 @@ add_entrypoint_object(
   HDRS
     ../dup3.h
   DEPENDS
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.dup3
     libc.src.errno.errno
 )
 
@@ -102,8 +88,7 @@ add_entrypoint_object(
     ../faccessat.h
   DEPENDS
     libc.hdr.fcntl_macros
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.faccessat
     libc.src.errno.errno
 )
 
@@ -114,9 +99,7 @@ add_entrypoint_object(
   HDRS
     ../fchdir.h
   DEPENDS
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.fchdir
     libc.src.errno.errno
 )
 
@@ -198,9 +181,7 @@ add_entrypoint_object(
   HDRS
     ../fsync.h
   DEPENDS
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.fsync
     libc.src.errno.errno
 )
 
@@ -393,10 +374,7 @@ add_entrypoint_object(
     ../lseek.h
   DEPENDS
     libc.hdr.types.off_t
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.lseek
     libc.src.errno.errno
 )
 
@@ -514,10 +492,7 @@ add_entrypoint_object(
   HDRS
     ../rmdir.h
   DEPENDS
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.rmdir
     libc.src.errno.errno
 )
 
@@ -530,10 +505,7 @@ add_entrypoint_object(
   DEPENDS
     libc.hdr.types.size_t
     libc.hdr.types.ssize_t
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.readlink
     libc.src.errno.errno
 )
 
@@ -546,10 +518,7 @@ add_entrypoint_object(
   DEPENDS
     libc.hdr.types.size_t
     libc.hdr.types.ssize_t
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.readlinkat
     libc.src.errno.errno
 )
 
@@ -643,10 +612,7 @@ add_entrypoint_object(
   HDRS
     ../unlink.h
   DEPENDS
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.unlink
     libc.src.errno.errno
 )
 
@@ -657,10 +623,7 @@ add_entrypoint_object(
   HDRS
     ../unlinkat.h
   DEPENDS
-    libc.hdr.fcntl_macros
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.unlinkat
     libc.src.errno.errno
 )
 

diff  --git a/libc/src/unistd/linux/access.cpp b/libc/src/unistd/linux/access.cpp
index f06eec5a8db6a..570ccf6a78eb2 100644
--- a/libc/src/unistd/linux/access.cpp
+++ b/libc/src/unistd/linux/access.cpp
@@ -8,28 +8,17 @@
 
 #include "src/unistd/access.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/access.h"
 #include "src/__support/common.h"
-
-#include "hdr/fcntl_macros.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, access, (const char *path, int mode)) {
-#ifdef SYS_access
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_access, path, mode);
-#elif defined(SYS_faccessat)
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_faccessat, AT_FDCWD, path, mode);
-#else
-#error "access and faccessat syscalls not available."
-#endif
-
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::access(path, mode);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;

diff  --git a/libc/src/unistd/linux/chdir.cpp b/libc/src/unistd/linux/chdir.cpp
index 04ba509b49a56..e7a668b620f94 100644
--- a/libc/src/unistd/linux/chdir.cpp
+++ b/libc/src/unistd/linux/chdir.cpp
@@ -8,19 +8,17 @@
 
 #include "src/unistd/chdir.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/chdir.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, chdir, (const char *path)) {
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_chdir, path);
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::chdir(path);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;

diff  --git a/libc/src/unistd/linux/dup.cpp b/libc/src/unistd/linux/dup.cpp
index 81d30c6cdbc4c..b9a8f9d0498df 100644
--- a/libc/src/unistd/linux/dup.cpp
+++ b/libc/src/unistd/linux/dup.cpp
@@ -8,22 +8,20 @@
 
 #include "src/unistd/dup.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/dup.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, dup, (int fd)) {
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_dup, fd);
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::dup(fd);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
-  return ret;
+  return ret.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/unistd/linux/dup2.cpp b/libc/src/unistd/linux/dup2.cpp
index 0a0e86573b34e..f081e1e685878 100644
--- a/libc/src/unistd/linux/dup2.cpp
+++ b/libc/src/unistd/linux/dup2.cpp
@@ -8,48 +8,20 @@
 
 #include "src/unistd/dup2.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/dup2.h"
 #include "src/__support/common.h"
-
-#include "hdr/fcntl_macros.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, dup2, (int oldfd, int newfd)) {
-#ifdef SYS_dup2
-  // If dup2 syscall is available, we make use of directly.
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_dup2, oldfd, newfd);
-#elif defined(SYS_dup3)
-  // If dup2 syscall is not available, we try using the dup3 syscall. However,
-  // dup3 fails if oldfd is the same as newfd. So, we handle that case
-  // separately before making the dup3 syscall.
-  if (oldfd == newfd) {
-    // Check if oldfd is actually a valid file descriptor.
-#if SYS_fcntl
-    int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, oldfd, F_GETFD);
-#elif defined(SYS_fcntl64)
-    // Same as fcntl but can handle large offsets
-    int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl64, oldfd, F_GETFD);
-#else
-#error "SYS_fcntl and SYS_fcntl64 syscalls not available."
-#endif
-    if (ret >= 0)
-      return oldfd;
-    libc_errno = -ret;
-    return -1;
-  }
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_dup3, oldfd, newfd, 0);
-#else
-#error "dup2 and dup3 syscalls not available."
-#endif
-  if (ret < 0) {
-    libc_errno = -ret;
+  auto result = linux_syscalls::dup2(oldfd, newfd);
+  if (!result) {
+    libc_errno = result.error();
     return -1;
   }
-  return ret;
+  return result.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/unistd/linux/dup3.cpp b/libc/src/unistd/linux/dup3.cpp
index 770fb73515b21..ce705f63373d1 100644
--- a/libc/src/unistd/linux/dup3.cpp
+++ b/libc/src/unistd/linux/dup3.cpp
@@ -8,22 +8,20 @@
 
 #include "src/unistd/dup3.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/dup3.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, dup3, (int oldfd, int newfd, int flags)) {
-  // If dup2 syscall is available, we make use of directly.
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_dup3, oldfd, newfd, flags);
-  if (ret >= 0)
-    return ret;
-  libc_errno = -ret;
-  return -1;
+  ErrorOr<int> ret = linux_syscalls::dup3(oldfd, newfd, flags);
+  if (!ret) {
+    libc_errno = ret.error();
+    return -1;
+  }
+  return ret.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/unistd/linux/faccessat.cpp b/libc/src/unistd/linux/faccessat.cpp
index 7a2a29cb0e901..41ad0f5a10f26 100644
--- a/libc/src/unistd/linux/faccessat.cpp
+++ b/libc/src/unistd/linux/faccessat.cpp
@@ -8,27 +8,18 @@
 
 #include "src/unistd/faccessat.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/faccessat.h"
 #include "src/__support/common.h"
-
-#include "hdr/fcntl_macros.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, faccessat,
                    (int fd, const char *path, int amode, int flag)) {
-#ifdef SYS_faccessat2
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_faccessat2, fd, path, amode, flag);
-#else
-#error "faccessat2 syscall is not available."
-#endif
-
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::faccessat(fd, path, amode, flag);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;

diff  --git a/libc/src/unistd/linux/fchdir.cpp b/libc/src/unistd/linux/fchdir.cpp
index f7a7422363e6e..f49545b4bd3e5 100644
--- a/libc/src/unistd/linux/fchdir.cpp
+++ b/libc/src/unistd/linux/fchdir.cpp
@@ -8,19 +8,17 @@
 
 #include "src/unistd/fchdir.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/fchdir.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, fchdir, (int fd)) {
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fchdir, fd);
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::fchdir(fd);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;

diff  --git a/libc/src/unistd/linux/fsync.cpp b/libc/src/unistd/linux/fsync.cpp
index fe08aed61e250..bf5796d793d70 100644
--- a/libc/src/unistd/linux/fsync.cpp
+++ b/libc/src/unistd/linux/fsync.cpp
@@ -8,22 +8,20 @@
 
 #include "src/unistd/fsync.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/fsync.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, fsync, (int fd)) {
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fsync, fd);
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::fsync(fd);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
-  return ret;
+  return 0;
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/unistd/linux/lseek.cpp b/libc/src/unistd/linux/lseek.cpp
index 26a08269fd8de..02ef338ecb45e 100644
--- a/libc/src/unistd/linux/lseek.cpp
+++ b/libc/src/unistd/linux/lseek.cpp
@@ -7,21 +7,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/unistd/lseek.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/lseek.h"
+#include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
-#include "src/__support/File/linux/lseekImpl.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
-#include "src/__support/common.h"
-
-#include "hdr/types/off_t.h"
-#include <sys/syscall.h> // For syscall numbers.
-
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(off_t, lseek, (int fd, off_t offset, int whence)) {
-  auto result = internal::lseekimpl(fd, offset, whence);
-  if (!result.has_value()) {
+  ErrorOr<off_t> result = linux_syscalls::lseek(fd, offset, whence);
+  if (!result) {
     libc_errno = result.error();
     return -1;
   }

diff  --git a/libc/src/unistd/linux/readlink.cpp b/libc/src/unistd/linux/readlink.cpp
index b297a41ca37bd..c029805d90224 100644
--- a/libc/src/unistd/linux/readlink.cpp
+++ b/libc/src/unistd/linux/readlink.cpp
@@ -8,33 +8,22 @@
 
 #include "src/unistd/readlink.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/readlink.h"
 #include "src/__support/common.h"
-
-#include "hdr/fcntl_macros.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(ssize_t, readlink,
                    (const char *__restrict path, char *__restrict buf,
                     size_t bufsize)) {
-#ifdef SYS_readlink
-  ssize_t ret =
-      LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_readlink, path, buf, bufsize);
-#elif defined(SYS_readlinkat)
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_readlinkat, AT_FDCWD,
-                                                      path, buf, bufsize);
-#else
-#error "readlink or readlinkat syscalls not available."
-#endif
-  if (ret < 0) {
-    libc_errno = static_cast<int>(-ret);
+  auto result = linux_syscalls::readlink(path, buf, bufsize);
+  if (!result) {
+    libc_errno = result.error();
     return -1;
   }
-  return ret;
+  return result.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/unistd/linux/readlinkat.cpp b/libc/src/unistd/linux/readlinkat.cpp
index cd0dcb8e0ff02..2c97d2f7b109a 100644
--- a/libc/src/unistd/linux/readlinkat.cpp
+++ b/libc/src/unistd/linux/readlinkat.cpp
@@ -8,26 +8,22 @@
 
 #include "src/unistd/readlinkat.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/readlinkat.h"
 #include "src/__support/common.h"
-
-#include "hdr/fcntl_macros.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(ssize_t, readlinkat,
                    (int fd, const char *__restrict path, char *__restrict buf,
                     size_t bufsize)) {
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_readlinkat, fd, path,
-                                                      buf, bufsize);
-  if (ret < 0) {
-    libc_errno = static_cast<int>(-ret);
+  auto result = linux_syscalls::readlinkat(fd, path, buf, bufsize);
+  if (!result) {
+    libc_errno = result.error();
     return -1;
   }
-  return ret;
+  return result.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/unistd/linux/rmdir.cpp b/libc/src/unistd/linux/rmdir.cpp
index eca6e954ef898..b7473a60c3fd2 100644
--- a/libc/src/unistd/linux/rmdir.cpp
+++ b/libc/src/unistd/linux/rmdir.cpp
@@ -8,28 +8,17 @@
 
 #include "src/unistd/rmdir.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/rmdir.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
-#include "hdr/fcntl_macros.h"
-#include <sys/syscall.h> // For syscall numbers.
-
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, rmdir, (const char *path)) {
-#ifdef SYS_rmdir
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_rmdir, path);
-#elif defined(SYS_unlinkat)
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_unlinkat, AT_FDCWD, path,
-                                              AT_REMOVEDIR);
-#else
-#error "rmdir and unlinkat syscalls not available."
-#endif
-
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::rmdir(path);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;

diff  --git a/libc/src/unistd/linux/unlink.cpp b/libc/src/unistd/linux/unlink.cpp
index 5fde2600937b2..bb1b5400042e7 100644
--- a/libc/src/unistd/linux/unlink.cpp
+++ b/libc/src/unistd/linux/unlink.cpp
@@ -8,27 +8,17 @@
 
 #include "src/unistd/unlink.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/unlink.h"
 #include "src/__support/common.h"
-
-#include "hdr/fcntl_macros.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, unlink, (const char *path)) {
-#ifdef SYS_unlink
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_unlink, path);
-#elif defined(SYS_unlinkat)
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_unlinkat, AT_FDCWD, path, 0);
-#else
-#error "unlink and unlinkat syscalls not available."
-#endif
-
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::unlink(path);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;

diff  --git a/libc/src/unistd/linux/unlinkat.cpp b/libc/src/unistd/linux/unlinkat.cpp
index b2012c52b8854..acb2e6d1936bb 100644
--- a/libc/src/unistd/linux/unlinkat.cpp
+++ b/libc/src/unistd/linux/unlinkat.cpp
@@ -8,25 +8,17 @@
 
 #include "src/unistd/unlinkat.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/unlinkat.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
-#include "hdr/fcntl_macros.h"
-#include <sys/syscall.h> // For syscall numbers.
-
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, unlinkat, (int dfd, const char *path, int flags)) {
-#ifdef SYS_unlinkat
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_unlinkat, dfd, path, flags);
-#else
-#error "unlinkat syscalls not available."
-#endif
-
-  if (ret < 0) {
-    libc_errno = -ret;
+  ErrorOr<int> ret = linux_syscalls::unlinkat(dfd, path, flags);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;


        


More information about the libc-commits mailing list