[libc-commits] [libc] e2464bf - [libc] Add struct sockaddr_in (#197909)

via libc-commits libc-commits at lists.llvm.org
Tue May 19 06:33:36 PDT 2026


Author: Pavel Labath
Date: 2026-05-19T15:33:29+02:00
New Revision: e2464bf702197349a1ec0691e4ab188ea9a18155

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

LOG: [libc] Add struct sockaddr_in (#197909)

The struct needs to be 16 bytes long for compatibility with the linux
kernel (which rejects smaller sizes, even though the reset of the bytes
are unused).

The padding field (and its name) is not specified by POSIX, but it's
traditionally called sin_zero, and there exists a fair amount of code
that references that name, so I'm matching it as well.

I'm testing the compatibility of this struct by binding to a localhost
address. This test requires that the machine has a loopback interface
with an assigned ipv4 address. If some of the environments do not have
it, we can try to detect this in the test and skip it, but this would
diminish the value of the test.

As a drive-by, I'm also adding the (non-POSIX) INADDR_LOOPBACK constant.

Assisted by Gemini.

Added: 
    libc/hdr/types/struct_sockaddr_in.h
    libc/include/llvm-libc-types/struct_sockaddr_in.h

Modified: 
    libc/hdr/types/CMakeLists.txt
    libc/include/CMakeLists.txt
    libc/include/llvm-libc-macros/netinet-in-macros.h
    libc/include/llvm-libc-types/CMakeLists.txt
    libc/include/netinet/in.yaml
    libc/test/src/sys/socket/linux/CMakeLists.txt
    libc/test/src/sys/socket/linux/bind_test.cpp
    libc/utils/docgen/netinet/in.yaml

Removed: 
    


################################################################################
diff  --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index aef7ed1f42e20..626c5fb82883e 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -465,6 +465,15 @@ add_proxy_header_library(
     libc.include.sys_socket
 )
 
+add_proxy_header_library(
+  struct_sockaddr_in
+  HDRS
+    struct_sockaddr_in.h
+  FULL_BUILD_DEPENDS
+    libc.include.llvm-libc-types.struct_sockaddr_in
+    libc.include.netinet_in
+)
+
 add_proxy_header_library(
   socklen_t
   HDRS

diff  --git a/libc/hdr/types/struct_sockaddr_in.h b/libc/hdr/types/struct_sockaddr_in.h
new file mode 100644
index 0000000000000..7fe17110c948b
--- /dev/null
+++ b/libc/hdr/types/struct_sockaddr_in.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Proxy for struct sockaddr_in.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_SOCKADDR_IN_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_SOCKADDR_IN_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_sockaddr_in.h"
+
+#else
+
+#include <netinet/in.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_SOCKADDR_IN_H

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index fc960ff60e986..6a02241b7d6a2 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -220,6 +220,8 @@ add_header_macro(
     .llvm-libc-types.in_addr_t
     .llvm-libc-types.in_port_t
     .llvm-libc-types.sa_family_t
+    .llvm-libc-types.struct_sockaddr_in
+    .llvm-libc-types.struct_in_addr
     .llvm_libc_common_h
 )
 

diff  --git a/libc/include/llvm-libc-macros/netinet-in-macros.h b/libc/include/llvm-libc-macros/netinet-in-macros.h
index f22f0bab33772..ca10e7ff10a70 100644
--- a/libc/include/llvm-libc-macros/netinet-in-macros.h
+++ b/libc/include/llvm-libc-macros/netinet-in-macros.h
@@ -30,6 +30,8 @@
 #define INADDR_ANY __LLVM_LIBC_CAST(static_cast, in_addr_t, 0x00000000)
 #define INADDR_BROADCAST __LLVM_LIBC_CAST(static_cast, in_addr_t, 0xffffffff)
 #define INADDR_NONE __LLVM_LIBC_CAST(static_cast, in_addr_t, 0xffffffff)
+// Not specified by POSIX, added in SVR4
+#define INADDR_LOOPBACK __LLVM_LIBC_CAST(static_cast, in_addr_t, 0x7f000001)
 
 #define INET_ADDRSTRLEN 16
 #define INET6_ADDRSTRLEN 46

diff  --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index d6a013d7f4c43..2904e0d07f76c 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -197,9 +197,10 @@ add_header(wint_t HDR wint_t.h)
 add_header(wctype_t HDR wctype_t.h)
 add_header(sa_family_t HDR sa_family_t.h)
 add_header(socklen_t HDR socklen_t.h)
-add_header(struct_sockaddr_un HDR struct_sockaddr_un.h DEPENDS .sa_family_t)
 add_header(struct_sockaddr HDR struct_sockaddr.h DEPENDS .sa_family_t)
+add_header(struct_sockaddr_in HDR struct_sockaddr_in.h DEPENDS .in_port_t .sa_family_t .struct_in_addr)
 add_header(struct_sockaddr_storage HDR struct_sockaddr_storage.h DEPENDS .sa_family_t)
+add_header(struct_sockaddr_un HDR struct_sockaddr_un.h DEPENDS .sa_family_t)
 add_header(struct_iovec HDR struct_iovec.h DEPENDS .size_t)
 add_header(struct_linger HDR struct_linger.h)
 add_header(struct_cmsghdr HDR struct_cmsghdr.h DEPENDS .size_t)

diff  --git a/libc/include/llvm-libc-types/struct_sockaddr_in.h b/libc/include/llvm-libc-types/struct_sockaddr_in.h
new file mode 100644
index 0000000000000..3875487178918
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_sockaddr_in.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Definition of struct sockaddr_in. This is the sockaddr specialization for
+/// AF_INET sockets, as defined by posix.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_SOCKADDR_IN_H
+#define LLVM_LIBC_TYPES_STRUCT_SOCKADDR_IN_H
+
+#include "in_port_t.h"
+#include "sa_family_t.h"
+#include "struct_in_addr.h"
+
+struct __attribute__((may_alias)) sockaddr_in {
+  sa_family_t sin_family; /* AF_INET */
+  in_port_t sin_port;
+  struct in_addr sin_addr;
+
+  // For historic reasons, AF_INET addresses are 16 bytes. Users are not
+  // expected to access the padding field, but it traditionally uses a
+  // non-private name.
+  char sin_zero[8];
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_SOCKADDR_IN_H

diff  --git a/libc/include/netinet/in.yaml b/libc/include/netinet/in.yaml
index 8d9749f36ab78..2354e656c4bfc 100644
--- a/libc/include/netinet/in.yaml
+++ b/libc/include/netinet/in.yaml
@@ -18,6 +18,8 @@ types:
   - type_name: in_port_t
   - type_name: in_addr_t
   - type_name: sa_family_t
+  - type_name: struct_sockaddr_in
+  - type_name: struct_in_addr
 enums: []
 objects: []
 functions: []

diff  --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt
index 5b10ed2e5df0e..3b0c9748056cf 100644
--- a/libc/test/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/test/src/sys/socket/linux/CMakeLists.txt
@@ -39,11 +39,15 @@ add_libc_unittest(
   DEPENDS
     .socket_test_support
     libc.include.sys_socket
+    libc.hdr.netinet_in_macros
     libc.hdr.sys_socket_macros
+    libc.hdr.types.struct_sockaddr_in
     libc.hdr.types.struct_sockaddr_un
+    libc.src.arpa.inet.htonl
     libc.src.errno.errno
     libc.src.sys.socket.socket
     libc.src.sys.socket.bind
+    libc.src.sys.socket.getsockname
     libc.src.stdio.remove
     libc.src.unistd.close
     libc.src.__support.CPP.scope

diff  --git a/libc/test/src/sys/socket/linux/bind_test.cpp b/libc/test/src/sys/socket/linux/bind_test.cpp
index ff0b7d1f44077..9a459a54ae7ee 100644
--- a/libc/test/src/sys/socket/linux/bind_test.cpp
+++ b/libc/test/src/sys/socket/linux/bind_test.cpp
@@ -6,20 +6,23 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "hdr/sys_socket_macros.h"
-#include "hdr/types/struct_sockaddr_un.h"
+#include "src/__support/CPP/scope.h"
+#include "src/arpa/inet/htonl.h"
+#include "src/stdio/remove.h"
 #include "src/sys/socket/bind.h"
+#include "src/sys/socket/getsockname.h"
 #include "src/sys/socket/socket.h"
-
-#include "src/stdio/remove.h"
 #include "src/unistd/close.h"
-
-#include "src/__support/CPP/scope.h"
 #include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 #include "test/src/sys/socket/linux/socket_test_support.h"
 
+#include "hdr/netinet_in_macros.h"
+#include "hdr/sys_socket_macros.h"
+#include "hdr/types/struct_sockaddr_in.h"
+#include "hdr/types/struct_sockaddr_un.h"
+
 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
 using LlvmLibcBindTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
@@ -43,3 +46,32 @@ TEST_F(LlvmLibcBindTest, BindLocalSocket) {
       Succeeds(0));
   ASSERT_THAT(LIBC_NAMESPACE::remove(SOCK_PATH), Succeeds(0));
 }
+
+TEST_F(LlvmLibcBindTest, BindInetSocket) {
+  int sock = LIBC_NAMESPACE::socket(AF_INET, SOCK_DGRAM, 0);
+  ASSERT_GE(sock, 0);
+  ASSERT_ERRNO_SUCCESS();
+  LIBC_NAMESPACE::cpp::scope_exit close_sock(
+      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(sock), Succeeds(0)); });
+
+  struct sockaddr_in my_addr;
+  my_addr.sin_family = AF_INET;
+  my_addr.sin_port = 0;
+  // Avoid expanding the htonl macro in overlay mode.
+  my_addr.sin_addr.s_addr = (LIBC_NAMESPACE::htonl)(INADDR_LOOPBACK);
+
+  ASSERT_THAT(
+      LIBC_NAMESPACE::bind(sock, reinterpret_cast<struct sockaddr *>(&my_addr),
+                           sizeof(struct sockaddr_in)),
+      Succeeds(0));
+
+  my_addr = {};
+  socklen_t len = sizeof(my_addr);
+  ASSERT_THAT(LIBC_NAMESPACE::getsockname(
+                  sock, reinterpret_cast<struct sockaddr *>(&my_addr), &len),
+              Succeeds(0));
+  ASSERT_EQ(len, static_cast<socklen_t>(sizeof(struct sockaddr_in)));
+  EXPECT_EQ(my_addr.sin_family, static_cast<sa_family_t>(AF_INET));
+  EXPECT_NE(my_addr.sin_port, static_cast<in_port_t>(0));
+  EXPECT_EQ(my_addr.sin_addr.s_addr, (LIBC_NAMESPACE::htonl)(INADDR_LOOPBACK));
+}

diff  --git a/libc/utils/docgen/netinet/in.yaml b/libc/utils/docgen/netinet/in.yaml
index 513a4eda689ee..215451858dc15 100644
--- a/libc/utils/docgen/netinet/in.yaml
+++ b/libc/utils/docgen/netinet/in.yaml
@@ -13,10 +13,12 @@ macros:
     in-latest-posix: ''
   INADDR_ANY:
     in-latest-posix: ''
-  INET6_ADDRSTRLEN:
-    in-latest-posix: ''
   INADDR_BROADCAST:
     in-latest-posix: ''
+  INADDR_LOOPBACK:
+    c-definition: ''
+  INET6_ADDRSTRLEN:
+    in-latest-posix: ''
   INET_ADDRSTRLEN:
     in-latest-posix: ''
   IPV6_JOIN_GROUP:


        


More information about the libc-commits mailing list