diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 97625b28a2555..81ff70d0086c6 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -1039,6 +1039,7 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.arpa.inet.htons libc.src.arpa.inet.inet_addr libc.src.arpa.inet.inet_aton + libc.src.arpa.inet.inet_ntoa libc.src.arpa.inet.inet_ntop libc.src.arpa.inet.ntohl libc.src.arpa.inet.ntohs diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 4395484968baa..eb3f9a77b889b 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -4,6 +4,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.arpa.inet.htons libc.src.arpa.inet.inet_addr libc.src.arpa.inet.inet_aton + libc.src.arpa.inet.inet_ntoa libc.src.arpa.inet.inet_ntop libc.src.arpa.inet.ntohl libc.src.arpa.inet.ntohs diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 1d00b995c85d7..d7e4408357658 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -4,6 +4,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.arpa.inet.htons libc.src.arpa.inet.inet_addr libc.src.arpa.inet.inet_aton + libc.src.arpa.inet.inet_ntoa libc.src.arpa.inet.inet_ntop libc.src.arpa.inet.ntohl libc.src.arpa.inet.ntohs diff --git a/libc/include/arpa/inet.yaml b/libc/include/arpa/inet.yaml index c7b5aed4267a9..6629974844186 100644 --- a/libc/include/arpa/inet.yaml +++ b/libc/include/arpa/inet.yaml @@ -22,7 +22,6 @@ types: - type_name: in_addr_t - type_name: socklen_t - type_name: struct_in_addr - - type_name: socklen_t enums: [] objects: [] functions: @@ -39,6 +38,12 @@ functions: arguments: - type: const char * - type: struct in_addr * + - name: inet_ntoa + standards: + - posix + return_type: char * + arguments: + - type: struct in_addr - name: inet_ntop standards: - posix diff --git a/libc/src/arpa/inet/CMakeLists.txt b/libc/src/arpa/inet/CMakeLists.txt index 9705d3c263188..9e065b474ca1e 100644 --- a/libc/src/arpa/inet/CMakeLists.txt +++ b/libc/src/arpa/inet/CMakeLists.txt @@ -51,6 +51,22 @@ add_entrypoint_object( libc.src.__support.net.address ) +add_entrypoint_object( + inet_ntoa + SRCS + inet_ntoa.cpp + HDRS + inet_ntoa.h + DEPENDS + libc.include.arpa_inet + libc.hdr.inet_address_macros + libc.hdr.types.struct_in_addr + libc.src.__support.common + libc.src.__support.CPP.span + libc.src.__support.macros.config + libc.src.__support.net.address +) + add_entrypoint_object( inet_ntop SRCS @@ -72,7 +88,6 @@ add_entrypoint_object( libc.src.__support.net.address ) - add_entrypoint_object( ntohl SRCS diff --git a/libc/src/arpa/inet/inet_ntoa.cpp b/libc/src/arpa/inet/inet_ntoa.cpp new file mode 100644 index 0000000000000..de213a3e6b27a --- /dev/null +++ b/libc/src/arpa/inet/inet_ntoa.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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 of inet_ntoa function. +/// +//===----------------------------------------------------------------------===// + +#include "src/arpa/inet/inet_ntoa.h" +#include "hdr/inet-address-macros.h" +#include "src/__support/CPP/span.h" +#include "src/__support/common.h" +#include "src/__support/net/address.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(char *, inet_ntoa, (struct in_addr in)) { + static LIBC_THREAD_LOCAL char buffer[INET_ADDRSTRLEN]; + // Buffer is large enough for any address. + (void)net::ipv4_to_str(in, cpp::span(buffer, INET_ADDRSTRLEN)); + return buffer; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/arpa/inet/inet_ntoa.h b/libc/src/arpa/inet/inet_ntoa.h new file mode 100644 index 0000000000000..054f7e35b5a41 --- /dev/null +++ b/libc/src/arpa/inet/inet_ntoa.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 +/// Implementation header of inet_ntoa. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_ARPA_INET_INET_NTOA_H +#define LLVM_LIBC_SRC_ARPA_INET_INET_NTOA_H + +#include "hdr/types/struct_in_addr.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +char *inet_ntoa(struct in_addr in); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_ARPA_INET_INET_NTOA_H diff --git a/libc/test/src/arpa/inet/CMakeLists.txt b/libc/test/src/arpa/inet/CMakeLists.txt index 5a6da519b2782..d6d92eacddabb 100644 --- a/libc/test/src/arpa/inet/CMakeLists.txt +++ b/libc/test/src/arpa/inet/CMakeLists.txt @@ -44,6 +44,18 @@ add_libc_unittest( libc.src.arpa.inet.inet_aton ) +add_libc_unittest( + inet_ntoa + SUITE + libc_arpa_inet_unittests + SRCS + inet_ntoa_test.cpp + DEPENDS + libc.src.arpa.inet.inet_ntoa + libc.hdr.types.struct_in_addr + libc.src.__support.endian_internal +) + add_libc_unittest( inet_ntop SUITE @@ -60,7 +72,6 @@ add_libc_unittest( libc.test.UnitTest.ErrnoCheckingTest ) - add_libc_unittest( ntohl SUITE diff --git a/libc/test/src/arpa/inet/inet_ntoa_test.cpp b/libc/test/src/arpa/inet/inet_ntoa_test.cpp new file mode 100644 index 0000000000000..bdc78644513b0 --- /dev/null +++ b/libc/test/src/arpa/inet/inet_ntoa_test.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 inet_ntoa. +/// +//===----------------------------------------------------------------------===// + +#include "hdr/types/struct_in_addr.h" +#include "src/__support/endian_internal.h" +#include "src/arpa/inet/inet_ntoa.h" +#include "test/UnitTest/Test.h" + +static struct in_addr make_addr(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { + struct in_addr addr; + addr.s_addr = LIBC_NAMESPACE::Endian::to_big_endian( + static_cast(a) << 24 | static_cast(b) << 16 | + static_cast(c) << 8 | static_cast(d)); + return addr; +} + +TEST(LlvmLibcInetNtoaTest, BasicConversion) { + EXPECT_STREQ("127.0.0.1", LIBC_NAMESPACE::inet_ntoa(make_addr(127, 0, 0, 1))); + EXPECT_STREQ("0.0.0.0", LIBC_NAMESPACE::inet_ntoa(make_addr(0, 0, 0, 0))); + EXPECT_STREQ("255.255.255.255", + LIBC_NAMESPACE::inet_ntoa(make_addr(255, 255, 255, 255))); + EXPECT_STREQ("192.168.1.100", + LIBC_NAMESPACE::inet_ntoa(make_addr(192, 168, 1, 100))); + EXPECT_STREQ("10.0.0.1", LIBC_NAMESPACE::inet_ntoa(make_addr(10, 0, 0, 1))); +} + +TEST(LlvmLibcInetNtoaTest, BufferReuseAndOverwrite) { + char *ptr1 = LIBC_NAMESPACE::inet_ntoa(make_addr(1, 2, 3, 4)); + EXPECT_STREQ("1.2.3.4", ptr1); + + char *ptr2 = LIBC_NAMESPACE::inet_ntoa(make_addr(5, 6, 7, 8)); + // Our implementation returns pointer to the same static buffer + EXPECT_EQ(ptr1, ptr2); + EXPECT_STREQ("5.6.7.8", ptr1); + EXPECT_STREQ("5.6.7.8", ptr2); +}