Browse Source

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.
pull/63/head
Dan Gohman 6 years ago
parent
commit
1db93d1169
  1. 3
      Makefile
  2. 1
      expected/wasm32-wasi/defined-symbols.txt
  3. 46
      libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_aton.c
  4. 112
      libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_ntop.c
  5. 153
      libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_pton.c

3
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 \

1
expected/wasm32-wasi/defined-symbols.txt

@ -84,6 +84,7 @@ __getentropy
__getopt_msg
__gmtime_r
__hwcap
__inet_aton
__intscan
__invtrigl_R
__isalnum_l

46
libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_aton.c

@ -1,46 +0,0 @@
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
//
// SPDX-License-Identifier: BSD-2-Clause
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdint.h>
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 <common/parser_strtoint.h>
#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;
}
}
}

112
libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_ntop.c

@ -1,112 +0,0 @@
// Copyright (c) 2015 Nuxi, https://nuxi.nl/
//
// SPDX-License-Identifier: BSD-2-Clause
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
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;
}
}

153
libc-bottom-half/cloudlibc/src/libc/arpa/inet/inet_pton.c

@ -1,153 +0,0 @@
// Copyright (c) 2015 Nuxi, https://nuxi.nl/
//
// SPDX-License-Identifier: BSD-2-Clause
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
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;
}
}
Loading…
Cancel
Save