From: Dan Gohman Date: Wed, 8 May 2019 18:58:46 +0000 (-0700) Subject: Switch from the cloudlibc inet_pton etc. to the musl versions. X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=1db93d116912b260cfc0924e935e7dda99cab37a;p=wasi-libc.git Switch from the cloudlibc inet_pton etc. to the musl versions. These functions aren't specific to the underlying system call interface, so they don't need to be in the "bottom half". This also fixes src/functional/inet_pton.c and src/regression/inet_pton-empty-last-field.c in musl's libc-test. --- diff --git a/Makefile b/Makefile index 40a072f..4b702cf 100644 --- a/Makefile +++ b/Makefile @@ -79,6 +79,9 @@ LIBC_TOP_HALF_MUSL_SOURCES = \ $(LIBC_TOP_HALF_MUSL_SRC_DIR)/network/htons.c \ $(LIBC_TOP_HALF_MUSL_SRC_DIR)/network/ntohl.c \ $(LIBC_TOP_HALF_MUSL_SRC_DIR)/network/ntohs.c \ + $(LIBC_TOP_HALF_MUSL_SRC_DIR)/network/inet_ntop.c \ + $(LIBC_TOP_HALF_MUSL_SRC_DIR)/network/inet_pton.c \ + $(LIBC_TOP_HALF_MUSL_SRC_DIR)/network/inet_aton.c \ $(LIBC_TOP_HALF_MUSL_SRC_DIR)/fenv/fenv.c \ $(LIBC_TOP_HALF_MUSL_SRC_DIR)/fenv/fesetround.c \ $(LIBC_TOP_HALF_MUSL_SRC_DIR)/exit/exit.c \ diff --git a/expected/wasm32-wasi/defined-symbols.txt b/expected/wasm32-wasi/defined-symbols.txt index e3c05d2..a5b1ec5 100644 --- a/expected/wasm32-wasi/defined-symbols.txt +++ b/expected/wasm32-wasi/defined-symbols.txt @@ -84,6 +84,7 @@ __getentropy __getopt_msg __gmtime_r __hwcap +__inet_aton __intscan __invtrigl_R __isalnum_l diff --git a/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_aton.c b/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_aton.c deleted file mode 100644 index 42f4c2f..0000000 --- a/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_aton.c +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2016 Nuxi, https://nuxi.nl/ -// -// SPDX-License-Identifier: BSD-2-Clause - -#include - -#include -#include - -int inet_aton(const char *cp, struct in_addr *inp) { - uint32_t max = UINT32_MAX; - uint32_t leading = 0; - int shift = 24; - for (;;) { - // Parse next part of the IPv4 address. - typedef uint32_t int_t; - uint32_t min = 0; - int base = 0; - bool allow_negative = false; -#define PEEK(n) cp[n] -#define SKIP(n) \ - do { \ - cp += (n); \ - } while (0) -#include -#undef PEEK -#undef SKIP - if (!have_number || have_overflow) - return 0; - - if (*cp == '\0') { - // End of string. Return the IPv4 address, combining the - // previously parsed leading bytes with the trailing number. - inp->s_addr = htonl(leading | number); - return 1; - } else if (shift > 0 && number <= UINT8_MAX && *cp++ == '.') { - // More components follow. - leading |= number << shift; - shift -= 8; - max >>= 8; - } else { - // Parse error. - return 0; - } - } -} diff --git a/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_ntop.c b/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_ntop.c deleted file mode 100644 index 9e8ac74..0000000 --- a/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_ntop.c +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2015 Nuxi, https://nuxi.nl/ -// -// SPDX-License-Identifier: BSD-2-Clause - -#include - -#include -#include - -#include -#include -#include -#include -#include - -static const char *inet_ntop_inet(const uint8_t *restrict src, - char *restrict dst, size_t size) { - // Format the address. - char buf[INET_ADDRSTRLEN]; - size_t len = - snprintf(buf, sizeof(buf), "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8, - src[0], src[1], src[2], src[3]); - - // Copy it back. - if (len >= size) { - errno = ENOSPC; - return NULL; - } - strlcpy(dst, buf, size); - return dst; -} - -static const char *inet_ntop_inet6(const struct in6_addr *restrict src, - char *restrict dst, size_t size) { - // Extract groups from address. - uint16_t groups[8]; - for (size_t i = 0; i < __arraycount(groups); ++i) - groups[i] = (uint16_t)src->s6_addr[i * 2] << 8 | src->s6_addr[i * 2 + 1]; - - // Find longest series of groups having value zero. - struct { - size_t start; - size_t len; - } zeroes_cur = {}, zeroes_best = {}; - for (size_t i = 0; i < __arraycount(groups); ++i) { - if (groups[i] == 0) { - if (zeroes_best.len < ++zeroes_cur.len) - zeroes_best = zeroes_cur; - } else { - zeroes_cur.start = i + 1; - zeroes_cur.len = 0; - } - } - - // Format the address. - char buf[INET6_ADDRSTRLEN]; - char *bufend = buf; - size_t i = 0; - int strip_colon = 1; - bool ipv4 = IN6_IS_ADDR_V4COMPAT(src) || IN6_IS_ADDR_V4MAPPED(src); - do { - size_t bufsize = buf + sizeof(buf) - bufend; - if (i == 6 && ipv4) { - // End address with IPv4 representation of the last four bytes. - bufend += - snprintf(bufend, bufsize, - &":%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8[strip_colon], - src->s6_addr[12], src->s6_addr[13], src->s6_addr[14], - src->s6_addr[15]); - break; - } else if (i == zeroes_best.start && zeroes_best.len > 1) { - *bufend++ = ':'; - *bufend++ = ':'; - i += zeroes_best.len; - strip_colon = 1; - } else { - bufend += snprintf(bufend, bufsize, &":%" PRIx16[strip_colon], groups[i]); - ++i; - strip_colon = 0; - } - } while (i < __arraycount(groups)); - *bufend++ = '\0'; - - // Copy it back. - size_t len = bufend - buf; - if (len > size) { - errno = ENOSPC; - return NULL; - } - memcpy(dst, buf, len); - return dst; -} - -const char *inet_ntop(int af, const void *restrict src, char *restrict dst, -#ifdef __wasilibc_unmodified_upstream // bug fix - size_t size) { -#else - socklen_t size) { -#endif - switch (af) { - case AF_INET: - return inet_ntop_inet(src, dst, size); - case AF_INET6: { - struct in6_addr v6addr; - memcpy(&v6addr, src, sizeof(v6addr)); - return inet_ntop_inet6(&v6addr, dst, size); - } - default: - errno = EAFNOSUPPORT; - return NULL; - } -} diff --git a/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_pton.c b/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_pton.c deleted file mode 100644 index 1264dbd..0000000 --- a/libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_pton.c +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2015 Nuxi, https://nuxi.nl/ -// -// SPDX-License-Identifier: BSD-2-Clause - -#include - -#include - -#include -#include -#include -#include - -static int inet_pton4(const char *restrict src, uint8_t *restrict dst) { - uint8_t addr[4]; - for (size_t group = 0; group < __arraycount(addr); ++group) { - // Parse number between 0 and 255. - if (*src == '0') { - // Zero. - addr[group] = 0; - ++src; - } else if (*src >= '1' && *src <= '9') { - // Number between 1 and 255. - unsigned int number = *src++ - '0'; - if (*src >= '0' && *src <= '9') - number = number * 10 + *src++ - '0'; - if (*src >= '0' && *src <= '9') - number = number * 10 + *src++ - '0'; - if (number > 255) - return 0; - addr[group] = number; - } else { - // Number should consist of at least one digit. - return 0; - } - - // Require a trailing null byte and dot separator between groups. - if (*src++ != (group == __arraycount(addr) - 1 ? '\0' : '.')) - return 0; - } - - // Copy result back. - memcpy(dst, addr, sizeof(addr)); - return 1; -} - -static int inet_pton6(const char *restrict src, uint8_t *restrict dst) { -#define NGROUPS 8 - uint8_t addr[NGROUPS * 2] = {}; - int leading_groups; - int groups; - - // Handle leading "::". - if (src[0] == ':' && src[1] == ':') { - if (src[2] == '\0') { - // The IPv6 null address. - memset(dst, '\0', NGROUPS * 2); - return 1; - } else { - // An address starting with "::", e.g. "::1". - leading_groups = 0; - groups = 2; - src += 2; - } - } else { - // Address should start with a group of numbers. - leading_groups = NGROUPS; - groups = 0; - } - - // Parse and groups of hexadecimal digits between 0 and ffff. - for (;;) { - const char *group_start = src; - uint_fast16_t number = 0; - for (int i = 0; i < 4; ++i) { - if (*src >= '0' && *src <= '9') { - number = number * 16 + *src++ - '0'; - } else if (*src >= 'A' && *src <= 'F') { - number = number * 16 + *src++ - 'A' + 10; - } else if (*src >= 'a' && *src <= 'f') { - number = number * 16 + *src++ - 'a' + 10; - } else if (i == 0) { - return 0; - } - } - addr[groups * 2] = number >> 8; - addr[groups * 2 + 1] = number; - - if (src[0] == ':' && src[1] == ':') { - // "::" Can only be used once. - ++groups; - if (leading_groups < groups) - return 0; - leading_groups = groups; - src += 2; - if (*src == '\0') { - // "::" placed at the end of an address. - if (groups > NGROUPS - 2) - return 0; - break; - } else { - // "::" placed somewhere in the middle of an address. - groups += 2; - } - } else if (*src == ':') { - // Group separator. - ++groups; - ++src; - } else if (*src == '\0') { - // End of address. - ++groups; - break; - } else { - // Potential trailing IPv4 address using dotted quad notation. - if (groups > NGROUPS - 2) - return 0; - if (inet_pton4(group_start, &addr[groups * 2]) != 1) - return 0; - groups += 2; - break; - } - - // Next iteration would attempt to parse a ninth group. - if (groups >= NGROUPS) - return 0; - } - - // Number of groups is insufficient, e.g. "1:2:3:4:5:6:7". - if (groups < leading_groups) - return 0; - - // Zero the destination address. Copy the leading groups to the start - // of the buffer and the trailing groups to the end. - memset(dst, '\0', NGROUPS * 2); - memcpy(dst, addr, leading_groups * 2); - size_t trailing_groups = groups - leading_groups; - memcpy(dst + (NGROUPS - trailing_groups) * 2, addr + leading_groups * 2, - trailing_groups * 2); -#undef NGROUPS - return 1; -} - -int inet_pton(int af, const char *restrict src, void *restrict dst) { - switch (af) { - case AF_INET: - return inet_pton4(src, dst); - case AF_INET6: - return inet_pton6(src, dst); - default: - errno = EAFNOSUPPORT; - return -1; - } -}