[libc-commits] [libc] 753ceec - [libc] Implement sockatmark (#205400)

via libc-commits libc-commits at lists.llvm.org
Mon Jul 6 01:43:54 PDT 2026


Author: Pavel Labath
Date: 2026-07-06T08:43:49Z
New Revision: 753ceecfdcdf43d626ddd9534cdf470572a8deda

URL: https://github.com/llvm/llvm-project/commit/753ceecfdcdf43d626ddd9534cdf470572a8deda
DIFF: https://github.com/llvm/llvm-project/commit/753ceecfdcdf43d626ddd9534cdf470572a8deda.diff

LOG: [libc] Implement sockatmark (#205400)

This patch implements sockatmark as a simple wrapper around
ioctl(SIOCATMARK).

I don't test it with actual out of band data, as that requires a TCP
connection, which is more complicated to set up.

Assisted by Gemini.

Added: 
    libc/src/sys/socket/linux/sockatmark.cpp
    libc/src/sys/socket/sockatmark.h
    libc/test/src/sys/socket/linux/sockatmark_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/riscv/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/include/sys/socket.yaml
    libc/src/sys/socket/CMakeLists.txt
    libc/src/sys/socket/linux/CMakeLists.txt
    libc/test/src/sys/socket/linux/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index bd17c6666d085..c20067edca55a 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -303,6 +303,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.socket.sendto
     libc.src.sys.socket.setsockopt
     libc.src.sys.socket.shutdown
+    libc.src.sys.socket.sockatmark
     libc.src.sys.socket.socket
     libc.src.sys.socket.socketpair
     # TODO: These functions are not compatible with 64-bit musl. They need to

diff  --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 3d215f8b20139..e71eefca04ace 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -303,6 +303,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.socket.sendto
     libc.src.sys.socket.setsockopt
     libc.src.sys.socket.shutdown
+    libc.src.sys.socket.sockatmark
     libc.src.sys.socket.socket
     libc.src.sys.socket.socketpair
     # TODO: These functions are not compatible with 64-bit musl. They need to

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index d4d86cee9e33a..d12f8d8c73a36 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -333,6 +333,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.socket.sendto
     libc.src.sys.socket.setsockopt
     libc.src.sys.socket.shutdown
+    libc.src.sys.socket.sockatmark
     libc.src.sys.socket.socket
     libc.src.sys.socket.socketpair
     # TODO: These functions are not compatible with 64-bit musl. They need to

diff  --git a/libc/include/sys/socket.yaml b/libc/include/sys/socket.yaml
index 18b8b9e750aa7..fb121fa805f3b 100644
--- a/libc/include/sys/socket.yaml
+++ b/libc/include/sys/socket.yaml
@@ -178,6 +178,12 @@ functions:
     arguments:
       - type: int
       - type: int
+  - name: sockatmark
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: int
   - name: socket
     standards:
       - posix

diff  --git a/libc/src/sys/socket/CMakeLists.txt b/libc/src/sys/socket/CMakeLists.txt
index 45c0aee6f6f3b..2806bb0a752ff 100644
--- a/libc/src/sys/socket/CMakeLists.txt
+++ b/libc/src/sys/socket/CMakeLists.txt
@@ -142,3 +142,10 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.shutdown
 )
+
+add_entrypoint_object(
+  sockatmark
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.sockatmark
+)

diff  --git a/libc/src/sys/socket/linux/CMakeLists.txt b/libc/src/sys/socket/linux/CMakeLists.txt
index 82a7554f80107..4e711ffeac58a 100644
--- a/libc/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/src/sys/socket/linux/CMakeLists.txt
@@ -276,3 +276,16 @@ add_entrypoint_object(
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
 )
+
+add_entrypoint_object(
+  sockatmark
+  SRCS
+    sockatmark.cpp
+  HDRS
+    ../sockatmark.h
+  DEPENDS
+    libc.include.sys_socket
+    libc.src.__support.common
+    libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
+    libc.src.errno.errno
+)

diff  --git a/libc/src/sys/socket/linux/sockatmark.cpp b/libc/src/sys/socket/linux/sockatmark.cpp
new file mode 100644
index 0000000000000..2f864b64d3270
--- /dev/null
+++ b/libc/src/sys/socket/linux/sockatmark.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of sockatmark.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/socket/sockatmark.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+
+// For SIOCATMARK. Can't use hdr/sys_ioctl_macros, as not all system library
+// versions define it.
+#include <linux/sockios.h> // For SIOCATMARK.
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, sockatmark, (int sockfd)) {
+  int mark = 0;
+  ErrorOr<int> result = linux_syscalls::ioctl(sockfd, SIOCATMARK, &mark);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+
+  return mark;
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/sys/socket/sockatmark.h b/libc/src/sys/socket/sockatmark.h
new file mode 100644
index 0000000000000..a3e1e2046fae8
--- /dev/null
+++ b/libc/src/sys/socket/sockatmark.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for sockatmark.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_SOCKET_SOCKATMARK_H
+#define LLVM_LIBC_SRC_SYS_SOCKET_SOCKATMARK_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int sockatmark(int sockfd);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_SOCKET_SOCKATMARK_H

diff  --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt
index fc02db4aec7a0..76585f6b9129d 100644
--- a/libc/test/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/test/src/sys/socket/linux/CMakeLists.txt
@@ -149,6 +149,24 @@ add_libc_unittest(
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
+add_libc_unittest(
+  sockatmark_test
+  SUITE
+    libc_sys_socket_unittests
+  SRCS
+    sockatmark_test.cpp
+  DEPENDS
+    libc.hdr.sys_socket_macros
+    libc.src.errno.errno
+    libc.src.sys.socket.sockatmark
+    libc.src.sys.socket.socketpair
+    libc.src.unistd.close
+    libc.src.unistd.pipe
+    libc.src.__support.CPP.scope
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
 add_libc_unittest(
   sockname_test
   SUITE

diff  --git a/libc/test/src/sys/socket/linux/sockatmark_test.cpp b/libc/test/src/sys/socket/linux/sockatmark_test.cpp
new file mode 100644
index 0000000000000..249bd298f4832
--- /dev/null
+++ b/libc/test/src/sys/socket/linux/sockatmark_test.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Unittests for sockatmark.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/sys_socket_macros.h" // For AF_UNIX and SOCK_DGRAM
+#include "src/__support/CPP/scope.h"
+#include "src/sys/socket/sockatmark.h"
+#include "src/sys/socket/socketpair.h"
+#include "src/unistd/close.h"
+#include "src/unistd/pipe.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+using LlvmLibcSockatmarkTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+using LIBC_NAMESPACE::cpp::scope_exit;
+
+TEST_F(LlvmLibcSockatmarkTest, SocketpairReturnsFalse) {
+  int sockpair[2] = {-1, -1};
+  ASSERT_THAT(LIBC_NAMESPACE::socketpair(AF_UNIX, SOCK_DGRAM, 0, sockpair),
+              Succeeds(0));
+  scope_exit close_sockpair([&] {
+    ASSERT_THAT(LIBC_NAMESPACE::close(sockpair[0]), Succeeds(0));
+    ASSERT_THAT(LIBC_NAMESPACE::close(sockpair[1]), Succeeds(0));
+  });
+
+  ASSERT_THAT(LIBC_NAMESPACE::sockatmark(sockpair[0]), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::sockatmark(sockpair[1]), Succeeds(0));
+}
+
+TEST_F(LlvmLibcSockatmarkTest, InvalidFdFails) {
+  ASSERT_THAT(LIBC_NAMESPACE::sockatmark(-1), Fails(EBADF));
+}
+
+TEST_F(LlvmLibcSockatmarkTest, NonSocketFdFails) {
+  int pipefd[2] = {-1, -1};
+  ASSERT_THAT(LIBC_NAMESPACE::pipe(pipefd), Succeeds(0));
+  scope_exit close_pipe([&] {
+    ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[0]), Succeeds(0));
+    ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[1]), Succeeds(0));
+  });
+
+  ASSERT_THAT(LIBC_NAMESPACE::sockatmark(pipefd[0]), Fails(ENOTTY));
+}


        


More information about the libc-commits mailing list