[libc-commits] [libc] [libc] prefer *at syscalls in sys/stat wrappers (PR #197940)

Kiriti Ponduri via libc-commits libc-commits at lists.llvm.org
Fri May 15 07:22:03 PDT 2026


https://github.com/udaykiriti updated https://github.com/llvm/llvm-project/pull/197940

>From 55bcd6e61aac9f340ee01a02c1da5d22ae872f02 Mon Sep 17 00:00:00 2001
From: udaykiriti <udaykiriti624 at gmail.com>
Date: Fri, 15 May 2026 19:38:05 +0530
Subject: [PATCH 1/2] [libc] prefer *at syscalls in sys/stat wrappers

  - These changes flips the #ifdef order to prefer the *at syscalls over
    normal ones.
  - In modern architectures, *at system calls are preferred over normal
    system calls cuz of safety issues.
  - So by checking for ""*at"" system calls first, we ensure better
    compatibility with modern systems.
  - After then normal syscalls moved else or elif for support to older
    ones.

Signed-off-by: udaykiriti <udaykiriti624 at gmail.com>
---
 .../__support/OSUtil/linux/syscall_wrappers/access.h   |  6 +++---
 .../src/__support/OSUtil/linux/syscall_wrappers/link.h | 10 +++++-----
 .../src/__support/OSUtil/linux/syscall_wrappers/open.h |  6 +++---
 .../__support/OSUtil/linux/syscall_wrappers/readlink.h |  8 ++++----
 .../__support/OSUtil/linux/syscall_wrappers/rmdir.h    |  6 +++---
 .../__support/OSUtil/linux/syscall_wrappers/unlink.h   |  6 +++---
 6 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/access.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/access.h
index 3f3a3bd343901..8fa68109cfed0 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/access.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/access.h
@@ -25,10 +25,10 @@ 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)
+#ifdef SYS_faccessat
   int ret = syscall_impl<int>(SYS_faccessat, AT_FDCWD, path, mode, 0);
+#elif defined(SYS_access)
+  int ret = syscall_impl<int>(SYS_access, path, mode);
 #else
 #error "access and faccessat syscalls not available."
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/link.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/link.h
index 048299b995588..ad27f09dd92bd 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/link.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/link.h
@@ -20,20 +20,20 @@ namespace LIBC_NAMESPACE_DECL {
 namespace linux_syscalls {
 
 LIBC_INLINE ErrorOr<int> link(const char *oldpath, const char *newpath) {
-#ifdef SYS_link
-  int ret = syscall_impl<int>(SYS_link, oldpath, newpath);
-#elif defined(SYS_linkat)
+#ifdef SYS_linkat
   int ret =
       syscall_impl<int>(SYS_linkat, AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
+#elif defined(SYS_link)
+  int ret = syscall_impl<int>(SYS_link, oldpath, newpath);
 #else
 #error "link and linkat syscalls not available."
 #endif
   if (ret < 0)
     return Error(-static_cast<int>(ret));
-  return 0;
+  return ret;
 }
 
 } // namespace linux_syscalls
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_LINK_H
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_LINK_H
\ No newline at end of file
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/open.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/open.h
index f487f2bb91637..e8825d1fe08ea 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/open.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/open.h
@@ -21,10 +21,10 @@ namespace LIBC_NAMESPACE_DECL {
 namespace linux_syscalls {
 
 LIBC_INLINE ErrorOr<int> open(const char *path, int flags, mode_t mode_flags) {
-#ifdef SYS_open
-  int fd = syscall_impl<int>(SYS_open, path, flags, mode_flags);
-#else
+#ifdef SYS_openat
   int fd = syscall_impl<int>(SYS_openat, AT_FDCWD, path, flags, mode_flags);
+#else
+  int fd = syscall_impl<int>(SYS_open, path, flags, mode_flags);
 #endif
   if (fd < 0)
     return Error(-fd);
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
index 7c6a0c8db0fee..c15bba151bb2d 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
@@ -27,11 +27,11 @@ 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)
+#ifdef SYS_readlinkat
   ssize_t ret =
       syscall_impl<ssize_t>(SYS_readlinkat, AT_FDCWD, path, buf, bufsiz);
+#elif defined(SYS_readlink)
+  ssize_t ret = syscall_impl<ssize_t>(SYS_readlink, path, buf, bufsiz);
 #else
 #error "readlink and readlinkat syscalls not available."
 #endif
@@ -43,4 +43,4 @@ LIBC_INLINE ErrorOr<ssize_t> readlink(const char *path, char *buf,
 } // namespace linux_syscalls
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINK_H
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINK_H
\ No newline at end of file
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/rmdir.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/rmdir.h
index cf8f03ce9fdfb..d123a9b240806 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/rmdir.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/rmdir.h
@@ -25,10 +25,10 @@ namespace LIBC_NAMESPACE_DECL {
 namespace linux_syscalls {
 
 LIBC_INLINE ErrorOr<int> rmdir(const char *path) {
-#ifdef SYS_rmdir
+#ifdef SYS_unlinkat
+  int ret = syscall_impl<int>(SYS_unlinkat, AT_FDCWD, path, 0);
+#elif defined(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
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/unlink.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/unlink.h
index 5549f794a3014..e04ebada8cb81 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/unlink.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/unlink.h
@@ -20,10 +20,10 @@ namespace LIBC_NAMESPACE_DECL {
 namespace linux_syscalls {
 
 LIBC_INLINE ErrorOr<int> unlink(const char *path) {
-#ifdef SYS_unlink
-  int ret = syscall_impl<int>(SYS_unlink, path);
-#elif defined(SYS_unlinkat)
+#ifdef SYS_unlinkat
   int ret = syscall_impl<int>(SYS_unlinkat, AT_FDCWD, path, 0);
+#elif defined(SYS_unlink)
+  int ret = syscall_impl<int>(SYS_unlink, path);
 #else
 #error "unlink and unlinkat syscalls not available."
 #endif

>From 3b75a6ca525ff4fd5c1587af796d36707b13be68 Mon Sep 17 00:00:00 2001
From: udaykiriti <udaykiriti624 at gmail.com>
Date: Fri, 15 May 2026 19:51:31 +0530
Subject: [PATCH 2/2] fixed the issue

Signed-off-by: udaykiriti <udaykiriti624 at gmail.com>
---
 libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
index c15bba151bb2d..0c2e01b2b4d80 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/readlink.h
@@ -43,4 +43,4 @@ LIBC_INLINE ErrorOr<ssize_t> readlink(const char *path, char *buf,
 } // namespace linux_syscalls
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINK_H
\ No newline at end of file
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_READLINK_H



More information about the libc-commits mailing list