[libc-commits] [libc] 86d4fad - [libc] Add remaining SO_ constants (#202278)

via libc-commits libc-commits at lists.llvm.org
Mon Jun 8 07:01:04 PDT 2026


Author: Pavel Labath
Date: 2026-06-08T16:00:59+02:00
New Revision: 86d4fadf5adb00089b2da5e3cdb4a38d8e0340fb

URL: https://github.com/llvm/llvm-project/commit/86d4fadf5adb00089b2da5e3cdb4a38d8e0340fb
DIFF: https://github.com/llvm/llvm-project/commit/86d4fadf5adb00089b2da5e3cdb4a38d8e0340fb.diff

LOG: [libc] Add remaining SO_ constants (#202278)

There are two complications here:
- These options have different values on some architectures. These
aren't architectures we're likely to support soon, but I've left a
#error so that it lights up in a porting attempt.
- The time-related options have two flavours, depending on the
sizeof(time_t). Since we now support only 64-bit time_t, and only
kernels newer than 5.10, we can unconditionally use the new versions
(released in 5.1). I added a test for one of the time options to verify
that it works.

Added: 
    

Modified: 
    libc/include/llvm-libc-macros/linux/sys-socket-macros.h
    libc/test/src/sys/socket/linux/CMakeLists.txt
    libc/test/src/sys/socket/linux/socketopt_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/include/llvm-libc-macros/linux/sys-socket-macros.h b/libc/include/llvm-libc-macros/linux/sys-socket-macros.h
index 1c6ae9f394f63..1d38d840aa342 100644
--- a/libc/include/llvm-libc-macros/linux/sys-socket-macros.h
+++ b/libc/include/llvm-libc-macros/linux/sys-socket-macros.h
@@ -30,6 +30,12 @@
 
 #define SOL_SOCKET 1
 
+// The values of the following constants 
diff er on some architectures
+#if defined(__parisc__) || defined(__alpha__) || defined(__sparc__) ||         \
+    defined(__powerpc__) || defined(__mips__)
+#error "Please check SO_ constant values"
+#endif
+
 #define SO_DEBUG 1
 #define SO_REUSEADDR 2
 #define SO_TYPE 3
@@ -45,6 +51,83 @@
 #define SO_LINGER 13
 #define SO_BSDCOMPAT 14
 #define SO_REUSEPORT 15
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+
+// The "old" options use a 32-bit time_t on 32-bit systems.
+// #define SO_RCVTIMEO_OLD 20
+// #define SO_SNDTIMEO_OLD 21
+
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+#define SO_BINDTODEVICE 25
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+#define SO_GET_FILTER SO_ATTACH_FILTER
+#define SO_PEERNAME 28
+// #define SO_TIMESTAMP_OLD 29
+#define SO_ACCEPTCONN 30
+#define SO_PEERSEC 31
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_PASSSEC 34
+// #define SO_TIMESTAMPNS_OLD 35
+#define SO_MARK 36
+// #define SO_TIMESTAMPING_OLD 37
+#define SO_PROTOCOL 38
+#define SO_DOMAIN 39
+#define SO_RXQ_OVFL 40
+#define SO_WIFI_STATUS 41
+#define SO_PEEK_OFF 42
+#define SO_NOFCS 43
+#define SO_LOCK_FILTER 44
+#define SO_SELECT_ERR_QUEUE 45
+#define SO_BUSY_POLL 46
+#define SO_MAX_PACING_RATE 47
+#define SO_BPF_EXTENSIONS 48
+#define SO_INCOMING_CPU 49
+#define SO_ATTACH_BPF 50
+#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+#define SO_CNX_ADVICE 53
+#define SCM_TIMESTAMPING_OPT_STATS 54
+#define SO_MEMINFO 55
+#define SO_INCOMING_NAPI_ID 56
+#define SO_COOKIE 57
+#define SCM_TIMESTAMPING_PKTINFO 58
+#define SO_PEERGROUPS 59
+#define SO_ZEROCOPY 60
+#define SO_TXTIME 61
+#define SO_BINDTOIFINDEX 62
+
+// These are the "new" options, which assume a 64-bit time_t, regardless of the
+// pointer size.
+#define SO_TIMESTAMP 63
+#define SO_TIMESTAMPNS 64
+#define SO_TIMESTAMPING 65
+#define SO_RCVTIMEO 66
+#define SO_SNDTIMEO 67
+
+#define SO_DETACH_REUSEPORT_BPF 68
+#define SO_PREFER_BUSY_POLL 69
+#define SO_BUSY_POLL_BUDGET 70
+#define SO_NETNS_COOKIE 71
+#define SO_BUF_LOCK 72
+#define SO_RESERVE_MEM 73
+#define SO_TXREHASH 74
+#define SO_RCVMARK 75
+#define SO_PASSPIDFD 76
+#define SO_PEERPIDFD 77
+#define SO_DEVMEM_LINEAR 78
+#define SO_DEVMEM_DMABUF 79
+#define SO_DEVMEM_DONTNEED 80
+#define SO_RCVPRIORITY 82
+#define SO_PASSRIGHTS 83
+#define SO_INQ 84
 
 #define SHUT_RD 0
 #define SHUT_WR 1

diff  --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt
index bcda617c4b28d..5e39b90813cb9 100644
--- a/libc/test/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/test/src/sys/socket/linux/CMakeLists.txt
@@ -116,10 +116,16 @@ add_libc_unittest(
     libc.hdr.sys_socket_macros
     libc.hdr.types.socklen_t
     libc.hdr.types.struct_linger
+    libc.hdr.time_macros
+    libc.hdr.types.struct_timespec
+    libc.hdr.types.struct_timeval
     libc.src.errno.errno
     libc.src.sys.socket.getsockopt
     libc.src.sys.socket.setsockopt
     libc.src.sys.socket.socket
+    libc.src.sys.socket.socketpair
+    libc.src.sys.socket.recv
+    libc.src.time.clock_gettime
     libc.src.unistd.close
     libc.src.unistd.pipe
     libc.src.__support.CPP.scope

diff  --git a/libc/test/src/sys/socket/linux/socketopt_test.cpp b/libc/test/src/sys/socket/linux/socketopt_test.cpp
index 5dcccf1095ae5..3af47c3f18a7d 100644
--- a/libc/test/src/sys/socket/linux/socketopt_test.cpp
+++ b/libc/test/src/sys/socket/linux/socketopt_test.cpp
@@ -7,10 +7,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "hdr/sys_socket_macros.h"
+#include "hdr/time_macros.h"
 #include "hdr/types/struct_linger.h"
+#include "hdr/types/struct_timespec.h"
+#include "hdr/types/struct_timeval.h"
 #include "src/sys/socket/getsockopt.h"
+#include "src/sys/socket/recv.h"
 #include "src/sys/socket/setsockopt.h"
 #include "src/sys/socket/socket.h"
+#include "src/sys/socket/socketpair.h"
+#include "src/time/clock_gettime.h"
 
 #include "src/unistd/close.h"
 #include "src/unistd/pipe.h"
@@ -108,3 +114,46 @@ TEST_F(LlvmLibcSocketOptTest, InvalidSocket) {
                                          &optlen),
               Fails(EBADF));
 }
+
+TEST_F(LlvmLibcSocketOptTest, ReceiveTimeout) {
+  int sv[2] = {0, 0};
+  ASSERT_THAT(LIBC_NAMESPACE::socketpair(AF_UNIX, SOCK_STREAM, 0, sv),
+              Succeeds(0));
+  scope_exit close_sv([&] {
+    ASSERT_THAT(LIBC_NAMESPACE::close(sv[0]), Succeeds(0));
+    ASSERT_THAT(LIBC_NAMESPACE::close(sv[1]), Succeeds(0));
+  });
+
+  struct timeval tv;
+  tv.tv_sec = 1;
+  tv.tv_usec = 0;
+  socklen_t optlen = sizeof(tv);
+  ASSERT_THAT(
+      LIBC_NAMESPACE::setsockopt(sv[0], SOL_SOCKET, SO_RCVTIMEO, &tv, optlen),
+      Succeeds(0));
+
+  // Retrieve option to verify it was set correctly.
+  struct timeval retrieved_tv;
+  retrieved_tv.tv_sec = 0;
+  retrieved_tv.tv_usec = 0;
+  socklen_t retrieved_optlen = sizeof(retrieved_tv);
+  ASSERT_THAT(LIBC_NAMESPACE::getsockopt(sv[0], SOL_SOCKET, SO_RCVTIMEO,
+                                         &retrieved_tv, &retrieved_optlen),
+              Succeeds(0));
+  ASSERT_EQ(retrieved_optlen, optlen);
+  ASSERT_EQ(retrieved_tv.tv_sec, tv.tv_sec);
+
+  char buffer[10];
+  struct timespec start, end;
+  ASSERT_EQ(LIBC_NAMESPACE::clock_gettime(CLOCK_MONOTONIC, &start), 0);
+  // Read/recv on empty socket should block for ~1s and fail with EAGAIN.
+  ASSERT_THAT(LIBC_NAMESPACE::recv(sv[0], buffer, sizeof(buffer), 0),
+              Fails<ssize_t>(EAGAIN));
+  ASSERT_EQ(LIBC_NAMESPACE::clock_gettime(CLOCK_MONOTONIC, &end), 0);
+
+  int64_t elapsed_seconds = end.tv_sec - start.tv_sec;
+  int64_t elapsed_nseconds = end.tv_nsec - start.tv_nsec;
+  int64_t elapsed_ms = elapsed_seconds * 1000 + elapsed_nseconds / 1000000;
+  ASSERT_GE(elapsed_ms, static_cast<int64_t>(1000));
+  ASSERT_LT(elapsed_ms, static_cast<int64_t>(10000));
+}


        


More information about the libc-commits mailing list