[libc-commits] [libc] [llvm] [libc] Fix sockatmark test (PR #210655)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Mon Jul 20 00:45:31 PDT 2026


https://github.com/labath created https://github.com/llvm/llvm-project/pull/210655

When writing the test, I assumed that (linux) domain sockets do not support OOB data, and that sockatmark returns 0, because it can never read it.

In fact, as of 2021, linux does support OOB on domain sockets, but this feature can be turned off at build time (CONFIG_AF_UNIX_OOB). In this case (or in the case of older kernels), the kernel returns an error (and the test fails).

Armed with this knowledge, I modify the test to test both "1" (OOB present) and "0" (no OOB data) casesby actually sending OOB data into the socket. I also use the send call to determine the presence of OOB support, and have the test skip itself if it is absent. OOB data only makes sense on stream sockets, so change the socketpair type to that.

>From badd6140d1fb4d97d9f2ce3615fad5737754fc1a Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 20 Jul 2026 08:44:33 +0200
Subject: [PATCH] [libc] Fix sockatmark test

When writing the test, I assumed that (linux) domain sockets do not
support OOB data, and that sockatmark returns 0, because it can never
read it.

In fact, as of 2021, linux does support OOB on domain sockets, but this
feature can be turned off at build time (CONFIG_AF_UNIX_OOB). In this
case (or in the case of older kernels), the kernel returns an error (and
the test fails).

Armed with this knowledge, I modify the test to test both "1" (OOB
present) and "0" (no OOB data) casesby actually sending OOB data into
the socket. I also use the send call to determine the presence of OOB
support, and have the test skip itself if it is absent.
---
 libc/test/src/sys/socket/linux/CMakeLists.txt   |  1 +
 .../src/sys/socket/linux/sockatmark_test.cpp    | 17 ++++++++++++++---
 .../libc/test/src/sys/socket/BUILD.bazel        |  2 ++
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt
index 57f90c3ba1862..54b4abda21e12 100644
--- a/libc/test/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/test/src/sys/socket/linux/CMakeLists.txt
@@ -166,6 +166,7 @@ add_libc_unittest(
   DEPENDS
     libc.hdr.sys_socket_macros
     libc.src.errno.errno
+    libc.src.sys.socket.send
     libc.src.sys.socket.sockatmark
     libc.src.sys.socket.socketpair
     libc.src.unistd.close
diff --git a/libc/test/src/sys/socket/linux/sockatmark_test.cpp b/libc/test/src/sys/socket/linux/sockatmark_test.cpp
index 249bd298f4832..3dc0dd19719a8 100644
--- a/libc/test/src/sys/socket/linux/sockatmark_test.cpp
+++ b/libc/test/src/sys/socket/linux/sockatmark_test.cpp
@@ -13,29 +13,40 @@
 
 #include "hdr/sys_socket_macros.h" // For AF_UNIX and SOCK_DGRAM
 #include "src/__support/CPP/scope.h"
+#include "src/sys/socket/send.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"
+#include "test/UnitTest/TestLogger.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) {
+TEST_F(LlvmLibcSockatmarkTest, Socketpair) {
   int sockpair[2] = {-1, -1};
-  ASSERT_THAT(LIBC_NAMESPACE::socketpair(AF_UNIX, SOCK_DGRAM, 0, sockpair),
+  ASSERT_THAT(LIBC_NAMESPACE::socketpair(AF_UNIX, SOCK_STREAM, 0, sockpair),
               Succeeds(0));
+  if (LIBC_NAMESPACE::send(sockpair[0], ".", 1, MSG_OOB) != 1) {
+    ASSERT_ERRNO_EQ(EOPNOTSUPP);
+    LIBC_NAMESPACE::testing::tlog << "No kernel support for AF_UNIX OOB\n";
+    ASSERT_THAT(LIBC_NAMESPACE::sockatmark(sockpair[0]), Fails(ENOTTY));
+    return;
+  }
+
   scope_exit close_sockpair([&] {
     ASSERT_THAT(LIBC_NAMESPACE::close(sockpair[0]), Succeeds(0));
     ASSERT_THAT(LIBC_NAMESPACE::close(sockpair[1]), Succeeds(0));
   });
 
+  // sockpair[1] has OOB data because we've sent it above. sockpair[0] does not
+  // because it's empty.
   ASSERT_THAT(LIBC_NAMESPACE::sockatmark(sockpair[0]), Succeeds(0));
-  ASSERT_THAT(LIBC_NAMESPACE::sockatmark(sockpair[1]), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::sockatmark(sockpair[1]), Succeeds(1));
 }
 
 TEST_F(LlvmLibcSockatmarkTest, InvalidFdFails) {
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/sys/socket/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/sys/socket/BUILD.bazel
index f3765376b3aec..f3a5f645e69a3 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/sys/socket/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/sys/socket/BUILD.bazel
@@ -224,8 +224,10 @@ libc_test(
         "//libc:close",
         "//libc:hdr_sys_socket_macros",
         "//libc:pipe",
+        "//libc:send",
         "//libc:sockatmark",
         "//libc:socketpair",
+        "//libc/test/UnitTest:test_logger",
     ],
 )
 



More information about the libc-commits mailing list