Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions libc/hdr/types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions libc/hdr/types/struct_sockaddr_in.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions libc/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)

Expand Down
2 changes: 2 additions & 0 deletions libc/include/llvm-libc-macros/netinet-in-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion libc/include/llvm-libc-types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
33 changes: 33 additions & 0 deletions libc/include/llvm-libc-types/struct_sockaddr_in.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions libc/include/netinet/in.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: []
4 changes: 4 additions & 0 deletions libc/test/src/sys/socket/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 38 additions & 6 deletions libc/test/src/sys/socket/linux/bind_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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.

@labath labath May 19, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For visibility, I needed to work around the fact that htonl is a macro in overlay mode. LMK if we have a better way to deal with this.

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));
}
6 changes: 4 additions & 2 deletions libc/utils/docgen/netinet/in.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading