[libc-commits] [libc] [libc] Create socketcall helper for Linux syscall wrappers (PR #196903)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Mon May 11 05:48:08 PDT 2026


https://github.com/labath updated https://github.com/llvm/llvm-project/pull/196903

>From 31de7d9489a6adc136e73d41756eafd86938f8fe Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 7 May 2026 15:07:24 +0000
Subject: [PATCH 1/2] [libc] Create socketcall helper for Linux syscall
 wrappers

This patch implements a generic socketcall variadic wrapper template
under linux/syscall_wrappers/socketcall.h and refactors socket functions
to use it.

Assisted by Gemini.
---
 .../linux/syscall_wrappers/CMakeLists.txt     | 17 +++++++
 .../OSUtil/linux/syscall_wrappers/accept.h    | 10 ++--
 .../OSUtil/linux/syscall_wrappers/accept4.h   |  8 +---
 .../OSUtil/linux/syscall_wrappers/connect.h   | 10 ++--
 .../linux/syscall_wrappers/getsockopt.h       |  9 ++--
 .../OSUtil/linux/syscall_wrappers/listen.h    |  8 ++--
 .../linux/syscall_wrappers/setsockopt.h       |  9 ++--
 .../OSUtil/linux/syscall_wrappers/shutdown.h  |  8 ++--
 .../linux/syscall_wrappers/socketcall.h       | 47 +++++++++++++++++++
 libc/src/sys/socket/linux/bind.cpp            | 13 ++---
 libc/src/sys/socket/linux/recv.cpp            | 16 +++----
 libc/src/sys/socket/linux/recvfrom.cpp        | 17 +++----
 libc/src/sys/socket/linux/recvmsg.cpp         | 12 ++---
 libc/src/sys/socket/linux/send.cpp            | 16 +++----
 libc/src/sys/socket/linux/sendmsg.cpp         | 12 ++---
 libc/src/sys/socket/linux/sendto.cpp          | 17 +++----
 libc/src/sys/socket/linux/socket.cpp          | 13 ++---
 libc/src/sys/socket/linux/socketpair.cpp      | 12 ++---
 18 files changed, 128 insertions(+), 126 deletions(-)
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h

diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 6418d6f83dbfa0..4e29e310f57994 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -37,12 +37,24 @@ add_header_library(
     libc.include.sys_syscall
 )
 
+add_header_library(
+  socketcall
+  HDRS
+    socketcall.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.include.sys_syscall
+)
+
 add_header_library(
   accept
   HDRS
     accept.h
   DEPENDS
     libc.src.__support.OSUtil.linux.syscall_wrappers.accept
+    libc.src.__support.OSUtil.linux.syscall_wrappers.socketcall
     libc.src.__support.common
     libc.src.__support.error_or
     libc.src.__support.libc_errno
@@ -57,6 +69,7 @@ add_header_library(
   HDRS
     accept4.h
   DEPENDS
+    libc.src.__support.OSUtil.linux.syscall_wrappers.socketcall
     libc.src.__support.common
     libc.src.__support.error_or
     libc.src.__support.libc_errno
@@ -72,6 +85,7 @@ add_header_library(
     connect.h
   DEPENDS
     libc.src.__support.OSUtil.linux.syscall_wrappers.connect
+    libc.src.__support.OSUtil.linux.syscall_wrappers.socketcall
     libc.src.__support.common
     libc.src.__support.error_or
     libc.src.__support.libc_errno
@@ -86,6 +100,7 @@ add_header_library(
   HDRS
     getsockopt.h
   DEPENDS
+    libc.src.__support.OSUtil.linux.syscall_wrappers.socketcall
     libc.src.__support.common
     libc.src.__support.error_or
     libc.src.__support.libc_errno
@@ -99,6 +114,7 @@ add_header_library(
   HDRS
     listen.h
   DEPENDS
+    libc.src.__support.OSUtil.linux.syscall_wrappers.socketcall
     libc.src.__support.common
     libc.src.__support.error_or
     libc.src.__support.libc_errno
@@ -124,6 +140,7 @@ add_header_library(
   HDRS
     setsockopt.h
   DEPENDS
+    libc.src.__support.OSUtil.linux.syscall_wrappers.socketcall
     libc.src.__support.common
     libc.src.__support.error_or
     libc.src.__support.libc_errno
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/accept.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/accept.h
index e661f4df1daaba..368eaf31641790 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/accept.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/accept.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ACCEPT_H
 
 #include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
@@ -25,14 +26,9 @@ namespace linux_syscalls {
 LIBC_INLINE ErrorOr<int> accept(int sockfd, struct sockaddr *addr,
                                 socklen_t *addrlen) {
 #ifdef SYS_accept
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_accept, sockfd, addr, addrlen);
+  int ret = syscall_impl<int>(SYS_accept, sockfd, addr, addrlen);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[3] = {static_cast<unsigned long>(sockfd),
-                                    reinterpret_cast<unsigned long>(addr),
-                                    reinterpret_cast<unsigned long>(addrlen)};
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_ACCEPT,
-                                              sockcall_args);
+  int ret = socketcall<int>(SYS_ACCEPT, sockfd, addr, addrlen);
 #else
 #error "accept and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h
index ebe82f189af50d..b43de526dab0eb 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ACCEPT4_H
 
 #include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
@@ -28,12 +29,7 @@ LIBC_INLINE ErrorOr<int> accept4(int sockfd, struct sockaddr *addr,
   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_accept4, sockfd, addr,
                                               addrlen, flags);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[4] = {static_cast<unsigned long>(sockfd),
-                                    reinterpret_cast<unsigned long>(addr),
-                                    reinterpret_cast<unsigned long>(addrlen),
-                                    static_cast<unsigned long>(flags)};
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_ACCEPT4,
-                                              sockcall_args);
+  int ret = socketcall<int>(SYS_ACCEPT4, sockfd, addr, addrlen, flags);
 #else
 #error "accept4 and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/connect.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/connect.h
index 6974546630b008..094cdc79743b18 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/connect.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/connect.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CONNECT_H
 
 #include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
@@ -25,14 +26,9 @@ namespace linux_syscalls {
 LIBC_INLINE ErrorOr<int> connect(int sockfd, const struct sockaddr *addr,
                                  socklen_t addrlen) {
 #ifdef SYS_connect
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_connect, sockfd, addr, addrlen);
+  int ret = syscall_impl<int>(SYS_connect, sockfd, addr, addrlen);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[3] = {static_cast<unsigned long>(sockfd),
-                                    reinterpret_cast<unsigned long>(addr),
-                                    static_cast<unsigned long>(addrlen)};
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_CONNECT,
-                                              sockcall_args);
+  int ret = socketcall<int>(SYS_CONNECT, sockfd, addr, addrlen);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getsockopt.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getsockopt.h
index 623ba58ebb2ed0..7498330a15ea26 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/getsockopt.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getsockopt.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETSOCKOPT_H
 
 #include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
@@ -27,12 +28,8 @@ LIBC_INLINE ErrorOr<int> getsockopt(int sockfd, int level, int optname,
   int ret =
       syscall_impl<int>(SYS_getsockopt, sockfd, level, optname, optval, optlen);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[5] = {static_cast<unsigned long>(sockfd),
-                                    static_cast<unsigned long>(level),
-                                    static_cast<unsigned long>(optname),
-                                    reinterpret_cast<unsigned long>(optval),
-                                    reinterpret_cast<unsigned long>(optlen)};
-  int ret = syscall_impl<int>(SYS_socketcall, SYS_GETSOCKOPT, sockcall_args);
+  int ret =
+      socketcall<int>(SYS_GETSOCKOPT, sockfd, level, optname, optval, optlen);
 #else
 #error "getsockopt and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/listen.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/listen.h
index 9de54ce0a9a9f6..cbc0c34cab33f3 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/listen.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/listen.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LISTEN_H
 
 #include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
@@ -22,12 +23,9 @@ namespace linux_syscalls {
 
 LIBC_INLINE ErrorOr<int> listen(int sockfd, int backlog) {
 #ifdef SYS_listen
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_listen, sockfd, backlog);
+  int ret = syscall_impl<int>(SYS_listen, sockfd, backlog);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[2] = {static_cast<unsigned long>(sockfd),
-                                    static_cast<unsigned long>(backlog)};
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_LISTEN,
-                                              sockcall_args);
+  int ret = socketcall<int>(SYS_LISTEN, sockfd, backlog);
 #else
 #error "listen and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/setsockopt.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/setsockopt.h
index d16c397bba6aca..d5f8e28f058dc8 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/setsockopt.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/setsockopt.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETSOCKOPT_H
 
 #include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
@@ -27,12 +28,8 @@ LIBC_INLINE ErrorOr<int> setsockopt(int sockfd, int level, int optname,
   int ret =
       syscall_impl<int>(SYS_setsockopt, sockfd, level, optname, optval, optlen);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[5] = {static_cast<unsigned long>(sockfd),
-                                    static_cast<unsigned long>(level),
-                                    static_cast<unsigned long>(optname),
-                                    reinterpret_cast<unsigned long>(optval),
-                                    static_cast<unsigned long>(optlen)};
-  int ret = syscall_impl<int>(SYS_socketcall, SYS_SETSOCKOPT, sockcall_args);
+  int ret =
+      socketcall<int>(SYS_SETSOCKOPT, sockfd, level, optname, optval, optlen);
 #else
 #error "setsockopt and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/shutdown.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/shutdown.h
index 2a9e92364f637a..bdab8a82e6a1ff 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/shutdown.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/shutdown.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SHUTDOWN_H
 
 #include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
@@ -22,12 +23,9 @@ namespace linux_syscalls {
 
 LIBC_INLINE ErrorOr<int> shutdown(int sockfd, int how) {
 #ifdef SYS_shutdown
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_shutdown, sockfd, how);
+  int ret = syscall_impl<int>(SYS_shutdown, sockfd, how);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[2] = {static_cast<unsigned long>(sockfd),
-                                    static_cast<unsigned long>(how)};
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_SHUTDOWN,
-                                              sockcall_args);
+  int ret = socketcall<int>(SYS_SHUTDOWN, sockfd, how);
 #else
 #error "shutdown and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h
new file mode 100644
index 00000000000000..c1aae0172e2a9f
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h
@@ -0,0 +1,47 @@
+//===-- Implementation header for socketcall wrapper ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SOCKETCALL_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SOCKETCALL_H
+
+#include "src/__support/CPP/type_traits/is_integral.h"
+#include "src/__support/CPP/type_traits/is_pointer.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+#ifdef SYS_socketcall
+
+template <typename T>
+LIBC_INLINE unsigned long socketcall_arg_cast_impl(T val) {
+  if constexpr (cpp::is_pointer_v<T>) {
+    return reinterpret_cast<unsigned long>(val);
+  } else {
+    static_assert(cpp::is_integral_v<T>, "Expected integral or pointer type.");
+    return static_cast<unsigned long>(val);
+  }
+}
+
+template <typename ReturnType, typename... Args>
+LIBC_INLINE ReturnType socketcall(int call, Args... args) {
+  unsigned long sockcall_args[sizeof...(Args)] = {
+      socketcall_arg_cast_impl(args)...};
+  return LIBC_NAMESPACE::syscall_impl<ReturnType>(SYS_socketcall, call,
+                                                  sockcall_args);
+}
+
+#endif // SYS_socketcall
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SOCKETCALL_H
diff --git a/libc/src/sys/socket/linux/bind.cpp b/libc/src/sys/socket/linux/bind.cpp
index 83a3d06f5380bf..0a14d764c4d8ea 100644
--- a/libc/src/sys/socket/linux/bind.cpp
+++ b/libc/src/sys/socket/linux/bind.cpp
@@ -8,9 +8,9 @@
 
 #include "src/sys/socket/bind.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
@@ -23,14 +23,9 @@ LLVM_LIBC_FUNCTION(int, bind,
                    (int socket, const struct sockaddr *address,
                     socklen_t address_len)) {
 #ifdef SYS_bind
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_bind, socket, address, address_len);
+  int ret = syscall_impl<int>(SYS_bind, socket, address, address_len);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[3] = {static_cast<unsigned long>(socket),
-                                    reinterpret_cast<unsigned long>(address),
-                                    static_cast<unsigned long>(address_len)};
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_BIND,
-                                              sockcall_args);
+  int ret = socketcall(SYS_BIND, socket, address, address_len);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/recv.cpp b/libc/src/sys/socket/linux/recv.cpp
index baf4de1b5eb546..015f870dfb8ad1 100644
--- a/libc/src/sys/socket/linux/recv.cpp
+++ b/libc/src/sys/socket/linux/recv.cpp
@@ -14,7 +14,8 @@
 #include "hdr/types/socklen_t.h"
 #include "hdr/types/ssize_t.h"
 #include "hdr/types/struct_sockaddr.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/sanitizer.h"
@@ -24,17 +25,12 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(ssize_t, recv,
                    (int sockfd, void *buf, size_t len, int flags)) {
 #ifdef SYS_recv
-  ssize_t ret =
-      LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_recv, sockfd, buf, len, flags);
+  ssize_t ret = syscall_impl<ssize_t>(SYS_recv, sockfd, buf, len, flags);
 #elif defined(SYS_recvfrom)
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
-      SYS_recvfrom, sockfd, buf, len, flags, nullptr, nullptr);
+  ssize_t ret = syscall_impl<ssize_t>(SYS_recvfrom, sockfd, buf, len, flags,
+                                      nullptr, nullptr);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[4] = {
-      static_cast<unsigned long>(sockfd), reinterpret_cast<unsigned long>(buf),
-      static_cast<unsigned long>(len), static_cast<unsigned long>(flags)};
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_socketcall, SYS_RECV,
-                                                      sockcall_args);
+  ssize_t ret = socketcall<ssize_t>(SYS_RECV, sockfd, buf, len, flags);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/recvfrom.cpp b/libc/src/sys/socket/linux/recvfrom.cpp
index 3d8397b478cc4d..18f8425008fc42 100644
--- a/libc/src/sys/socket/linux/recvfrom.cpp
+++ b/libc/src/sys/socket/linux/recvfrom.cpp
@@ -14,7 +14,8 @@
 #include "hdr/types/socklen_t.h"
 #include "hdr/types/ssize_t.h"
 #include "hdr/types/struct_sockaddr.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/sanitizer.h"
@@ -35,17 +36,11 @@ LLVM_LIBC_FUNCTION(ssize_t, recvfrom,
   (void)srcaddr_sz; // prevent "set but not used" warning
 
 #ifdef SYS_recvfrom
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
-      SYS_recvfrom, sockfd, buf, len, flags, src_addr, addrlen);
+  ssize_t ret = syscall_impl<ssize_t>(SYS_recvfrom, sockfd, buf, len, flags,
+                                      src_addr, addrlen);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[6] = {static_cast<unsigned long>(sockfd),
-                                    reinterpret_cast<unsigned long>(buf),
-                                    static_cast<unsigned long>(len),
-                                    static_cast<unsigned long>(flags),
-                                    reinterpret_cast<unsigned long>(src_addr),
-                                    static_cast<unsigned long>(addrlen)};
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
-      SYS_socketcall, SYS_RECVFROM, sockcall_args);
+  ssize_t ret = socketcall<ssize_t>(SYS_RECVFROM, sockfd, buf, len, flags,
+                                    src_addr, addrlen);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/recvmsg.cpp b/libc/src/sys/socket/linux/recvmsg.cpp
index bc6d072dbf9a10..7de70752f9294a 100644
--- a/libc/src/sys/socket/linux/recvmsg.cpp
+++ b/libc/src/sys/socket/linux/recvmsg.cpp
@@ -13,7 +13,8 @@
 
 #include "hdr/types/ssize_t.h"
 #include "hdr/types/struct_msghdr.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/sanitizer.h"
@@ -22,14 +23,9 @@ namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(ssize_t, recvmsg, (int sockfd, msghdr *msg, int flags)) {
 #ifdef SYS_recvmsg
-  ssize_t ret =
-      LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_recvmsg, sockfd, msg, flags);
+  ssize_t ret = syscall_impl<ssize_t>(SYS_recvmsg, sockfd, msg, flags);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[3] = {static_cast<unsigned long>(sockfd),
-                                    reinterpret_cast<unsigned long>(msg),
-                                    static_cast<unsigned long>(flags)};
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
-      SYS_socketcall, SYS_RECVMSG, sockcall_args);
+  ssize_t ret = socketcall<ssize_t>(SYS_RECVMSG, sockfd, msg, flags);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/send.cpp b/libc/src/sys/socket/linux/send.cpp
index 43b01e7e6e0f6d..196425c4b2c43b 100644
--- a/libc/src/sys/socket/linux/send.cpp
+++ b/libc/src/sys/socket/linux/send.cpp
@@ -14,7 +14,8 @@
 #include "hdr/types/socklen_t.h"
 #include "hdr/types/ssize_t.h"
 #include "hdr/types/struct_sockaddr.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 
@@ -23,17 +24,12 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(ssize_t, send,
                    (int sockfd, const void *buf, size_t len, int flags)) {
 #ifdef SYS_send
-  ssize_t ret =
-      LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_send, sockfd, buf, len, flags);
+  ssize_t ret = syscall_impl<ssize_t>(SYS_send, sockfd, buf, len, flags);
 #elif defined(SYS_sendto)
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_sendto, sockfd, buf,
-                                                      len, flags, nullptr, 0);
+  ssize_t ret =
+      syscall_impl<ssize_t>(SYS_sendto, sockfd, buf, len, flags, nullptr, 0);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[4] = {
-      static_cast<unsigned long>(sockfd), reinterpret_cast<unsigned long>(buf),
-      static_cast<unsigned long>(len), static_cast<unsigned long>(flags)};
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_socketcall, SYS_SEND,
-                                                      sockcall_args);
+  ssize_t ret = socketcall<ssize_t>(SYS_SEND, sockfd, buf, len, flags);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/sendmsg.cpp b/libc/src/sys/socket/linux/sendmsg.cpp
index b04783ebfe7e7e..ebacef19ff42e7 100644
--- a/libc/src/sys/socket/linux/sendmsg.cpp
+++ b/libc/src/sys/socket/linux/sendmsg.cpp
@@ -13,7 +13,8 @@
 
 #include "hdr/types/ssize_t.h"
 #include "hdr/types/struct_msghdr.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 
@@ -22,14 +23,9 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(ssize_t, sendmsg,
                    (int sockfd, const struct msghdr *msg, int flags)) {
 #ifdef SYS_sendmsg
-  ssize_t ret =
-      LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_sendmsg, sockfd, msg, flags);
+  ssize_t ret = syscall_impl<ssize_t>(SYS_sendmsg, sockfd, msg, flags);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[3] = {static_cast<unsigned long>(sockfd),
-                                    reinterpret_cast<unsigned long>(msg),
-                                    static_cast<unsigned long>(flags)};
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
-      SYS_socketcall, SYS_SENDMSG, sockcall_args);
+  ssize_t ret = socketcall<ssize_t>(SYS_SENDMSG, sockfd, msg, flags);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/sendto.cpp b/libc/src/sys/socket/linux/sendto.cpp
index 9dda127f872d50..d809ecec549ffe 100644
--- a/libc/src/sys/socket/linux/sendto.cpp
+++ b/libc/src/sys/socket/linux/sendto.cpp
@@ -14,7 +14,8 @@
 #include "hdr/types/socklen_t.h"
 #include "hdr/types/ssize_t.h"
 #include "hdr/types/struct_sockaddr.h"
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 
@@ -24,17 +25,11 @@ LLVM_LIBC_FUNCTION(ssize_t, sendto,
                    (int sockfd, const void *buf, size_t len, int flags,
                     const struct sockaddr *dest_addr, socklen_t addrlen)) {
 #ifdef SYS_sendto
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
-      SYS_sendto, sockfd, buf, len, flags, dest_addr, addrlen);
+  ssize_t ret = syscall_impl<ssize_t>(SYS_sendto, sockfd, buf, len, flags,
+                                      dest_addr, addrlen);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[6] = {static_cast<unsigned long>(sockfd),
-                                    reinterpret_cast<unsigned long>(buf),
-                                    static_cast<unsigned long>(len),
-                                    static_cast<unsigned long>(flags),
-                                    reinterpret_cast<unsigned long>(dest_addr),
-                                    static_cast<unsigned long>(addrlen)};
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
-      SYS_socketcall, SYS_SENDTO, sockcall_args);
+  ssize_t ret = socketcall<ssize_t>(SYS_SENDTO, sockfd, buf, len, flags,
+                                    dest_addr, addrlen);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/socket.cpp b/libc/src/sys/socket/linux/socket.cpp
index 69eb6cfa01ced6..d601e0047a5144 100644
--- a/libc/src/sys/socket/linux/socket.cpp
+++ b/libc/src/sys/socket/linux/socket.cpp
@@ -8,9 +8,9 @@
 
 #include "src/sys/socket/socket.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
-
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
@@ -21,14 +21,9 @@ namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, socket, (int domain, int type, int protocol)) {
 #ifdef SYS_socket
-  int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_socket, domain, type, protocol);
+  int ret = syscall_impl<int>(SYS_socket, domain, type, protocol);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[3] = {static_cast<unsigned long>(domain),
-                                    static_cast<unsigned long>(type),
-                                    static_cast<unsigned long>(protocol)};
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_SOCKET,
-                                              sockcall_args);
+  int ret = socketcall(SYS_SOCKET, domain, type, protocol);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/socketpair.cpp b/libc/src/sys/socket/linux/socketpair.cpp
index 7ea8ca46cee586..f65f59950752ae 100644
--- a/libc/src/sys/socket/linux/socketpair.cpp
+++ b/libc/src/sys/socket/linux/socketpair.cpp
@@ -8,7 +8,8 @@
 
 #include "src/sys/socket/socketpair.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall_wrappers/socketcall.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
@@ -21,14 +22,9 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(int, socketpair,
                    (int domain, int type, int protocol, int sv[2])) {
 #ifdef SYS_socketpair
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketpair, domain, type,
-                                              protocol, sv);
+  int ret = syscall_impl<int>(SYS_socketpair, domain, type, protocol, sv);
 #elif defined(SYS_socketcall)
-  unsigned long sockcall_args[3] = {
-      static_cast<unsigned long>(domain), static_cast<unsigned long>(type),
-      static_cast<unsigned long>(protocol), static_cast<unsigned long>(sv)};
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_SOCKETPAIR,
-                                              sockcall_args);
+  int ret = socketcall(SYS_SOCKETPAIR, domain, type, protocol, sv);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif

>From 7fe3d2d8000aa420e9393c03158d34a02551189a Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 11 May 2026 12:47:19 +0000
Subject: [PATCH 2/2] fix calls

---
 libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h    | 3 +--
 libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h | 2 +-
 libc/src/sys/socket/linux/bind.cpp                            | 3 ++-
 libc/src/sys/socket/linux/socket.cpp                          | 2 +-
 libc/src/sys/socket/linux/socketpair.cpp                      | 3 ++-
 5 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h
index b43de526dab0eb..8761948e7afbf8 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/accept4.h
@@ -26,8 +26,7 @@ namespace linux_syscalls {
 LIBC_INLINE ErrorOr<int> accept4(int sockfd, struct sockaddr *addr,
                                  socklen_t *addrlen, int flags) {
 #ifdef SYS_accept4
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_accept4, sockfd, addr,
-                                              addrlen, flags);
+  int ret = syscall_impl<int>(SYS_accept4, sockfd, addr, addrlen, flags);
 #elif defined(SYS_socketcall)
   int ret = socketcall<int>(SYS_ACCEPT4, sockfd, addr, addrlen, flags);
 #else
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h
index c1aae0172e2a9f..72eb6b13bb9aa6 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/socketcall.h
@@ -1,4 +1,4 @@
-//===-- Implementation header for socketcall wrapper ------------*- C++ -*-===//
+//===-- Implementation header for socketcall wrapper ----------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/sys/socket/linux/bind.cpp b/libc/src/sys/socket/linux/bind.cpp
index 0a14d764c4d8ea..f8c0028d3f1c43 100644
--- a/libc/src/sys/socket/linux/bind.cpp
+++ b/libc/src/sys/socket/linux/bind.cpp
@@ -25,7 +25,8 @@ LLVM_LIBC_FUNCTION(int, bind,
 #ifdef SYS_bind
   int ret = syscall_impl<int>(SYS_bind, socket, address, address_len);
 #elif defined(SYS_socketcall)
-  int ret = socketcall(SYS_BIND, socket, address, address_len);
+  int ret =
+      linux_syscalls::socketcall<int>(SYS_BIND, socket, address, address_len);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/socket.cpp b/libc/src/sys/socket/linux/socket.cpp
index d601e0047a5144..986cffd37042b6 100644
--- a/libc/src/sys/socket/linux/socket.cpp
+++ b/libc/src/sys/socket/linux/socket.cpp
@@ -23,7 +23,7 @@ LLVM_LIBC_FUNCTION(int, socket, (int domain, int type, int protocol)) {
 #ifdef SYS_socket
   int ret = syscall_impl<int>(SYS_socket, domain, type, protocol);
 #elif defined(SYS_socketcall)
-  int ret = socketcall(SYS_SOCKET, domain, type, protocol);
+  int ret = linux_syscalls::socketcall<int>(SYS_SOCKET, domain, type, protocol);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif
diff --git a/libc/src/sys/socket/linux/socketpair.cpp b/libc/src/sys/socket/linux/socketpair.cpp
index f65f59950752ae..058522a768e8b8 100644
--- a/libc/src/sys/socket/linux/socketpair.cpp
+++ b/libc/src/sys/socket/linux/socketpair.cpp
@@ -24,7 +24,8 @@ LLVM_LIBC_FUNCTION(int, socketpair,
 #ifdef SYS_socketpair
   int ret = syscall_impl<int>(SYS_socketpair, domain, type, protocol, sv);
 #elif defined(SYS_socketcall)
-  int ret = socketcall(SYS_SOCKETPAIR, domain, type, protocol, sv);
+  int ret = linux_syscalls::socketcall<int>(SYS_SOCKETPAIR, domain, type,
+                                            protocol, sv);
 #else
 #error "socket and socketcall syscalls unavailable for this platform."
 #endif



More information about the libc-commits mailing list