[libc] Implement inet_ntoa (#208702)
Implement inet_ntoa, reusing the internal net::ipv4_to_str helper that backs inet_ntop. The result is stored in a *thread-local* static buffer. A thread-local buffer is not required for POSIX conformance, but there is some precedent for that, both in llvm libc (e.g. `strsignal`) and in glibc (whose `inet_ntoa` uses it). I'm doing the same for maximum compatiblity. Assisted by Gemini.
This commit is contained in:
parent
7881a37588
commit
89fa7352a2
9 changed files with 138 additions and 3 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
29
libc/src/arpa/inet/inet_ntoa.cpp
Normal file
29
libc/src/arpa/inet/inet_ntoa.cpp
Normal file
|
|
@ -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<char>(buffer, INET_ADDRSTRLEN));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
26
libc/src/arpa/inet/inet_ntoa.h
Normal file
26
libc/src/arpa/inet/inet_ntoa.h
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
46
libc/test/src/arpa/inet/inet_ntoa_test.cpp
Normal file
46
libc/test/src/arpa/inet/inet_ntoa_test.cpp
Normal file
|
|
@ -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<uint32_t>(a) << 24 | static_cast<uint32_t>(b) << 16 |
|
||||
static_cast<uint32_t>(c) << 8 | static_cast<uint32_t>(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);
|
||||
}
|
||||
Loading…
Reference in a new issue