summaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/inet/ether_addr.c1
-rw-r--r--libc/inet/getaddrinfo.c1393
-rw-r--r--libc/inet/gethostent_r.c (renamed from libc/inet/resolvename.c)2
-rw-r--r--libc/inet/herror.c14
-rw-r--r--libc/inet/hostid.c2
-rw-r--r--libc/inet/ifaddrs.c22
-rw-r--r--libc/inet/ifaddrs.h76
-rw-r--r--libc/inet/netlinkaccess.h25
-rw-r--r--libc/inet/rpc/rpc_thread.c2
-rw-r--r--libc/inet/socketcalls.c34
-rw-r--r--libc/pwd_grp/__getgrouplist_internal.c8
-rw-r--r--libc/pwd_grp/getgrouplist.c (renamed from libc/inet/resolveaddress.c)4
-rw-r--r--libc/pwd_grp/pwd_grp.c129
-rw-r--r--libc/stdio/open_memstream.c4
-rw-r--r--libc/stdio/vsnprintf.c2
15 files changed, 787 insertions, 931 deletions
diff --git a/libc/inet/ether_addr.c b/libc/inet/ether_addr.c
index bcea9ba46..8e19a0f09 100644
--- a/libc/inet/ether_addr.c
+++ b/libc/inet/ether_addr.c
@@ -31,7 +31,6 @@
#include <netinet/ether.h>
#include <netinet/if_ether.h>
-libc_hidden_proto(ether_aton_r)
libc_hidden_proto(ether_ntoa_r)
libc_hidden_proto(sprintf)
#ifdef __UCLIBC_HAS_XLOCALE__
diff --git a/libc/inet/getaddrinfo.c b/libc/inet/getaddrinfo.c
index 25c1c32fa..82c784075 100644
--- a/libc/inet/getaddrinfo.c
+++ b/libc/inet/getaddrinfo.c
@@ -58,7 +58,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
-#include <resolv.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
@@ -68,7 +67,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/un.h>
#include <sys/utsname.h>
#include <net/if.h>
-#include "ifaddrs.h"
+#include <ifaddrs.h>
/* Experimentally off - libc_hidden_proto(memcpy) */
/* Experimentally off - libc_hidden_proto(memset) */
@@ -80,7 +79,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
libc_hidden_proto(socket)
libc_hidden_proto(close)
libc_hidden_proto(getservbyname_r)
-libc_hidden_proto(gethostbyname_r)
libc_hidden_proto(gethostbyname2_r)
libc_hidden_proto(gethostbyaddr_r)
libc_hidden_proto(inet_pton)
@@ -100,888 +98,795 @@ libc_hidden_proto(in6addr_loopback)
#define UNIX_PATH_MAX 108
#endif
-struct gaih_service
-{
- const char *name;
- int num;
+/* Useful for having small structure members/global variables */
+typedef int8_t socktype_t;
+typedef int8_t family_t;
+typedef int8_t protocol_t;
+struct BUG_too_small {
+ char BUG_socktype_t_too_small[(0
+ | SOCK_STREAM
+ | SOCK_DGRAM
+ | SOCK_RAW
+ ) <= 127 ? 1 : -1];
+ char BUG_family_t_too_small[(0
+ | AF_UNSPEC
+ | AF_INET
+ | AF_INET6
+ ) <= 127 ? 1 : -1];
+ char BUG_protocol_t_too_small[(0
+ | IPPROTO_TCP
+ | IPPROTO_UDP
+ ) <= 127 ? 1 : -1];
};
-struct gaih_servtuple
-{
- struct gaih_servtuple *next;
- int socktype;
- int protocol;
- int port;
+struct gaih_service {
+ const char *name;
+ int num;
};
-static const struct gaih_servtuple nullserv;
-
-struct gaih_addrtuple
-{
- struct gaih_addrtuple *next;
- int family;
- char addr[16];
- uint32_t scopeid;
+struct gaih_servtuple {
+ struct gaih_servtuple *next;
+ int socktype;
+ int protocol;
+ int port;
};
-struct gaih_typeproto
-{
- int socktype;
- int protocol;
- char name[4];
- int protoflag;
+struct gaih_addrtuple {
+ struct gaih_addrtuple *next;
+ int family;
+ char addr[16];
+ uint32_t scopeid;
};
+struct gaih_typeproto {
+ socktype_t socktype;
+ protocol_t protocol;
+ int8_t protoflag;
+ char name[4];
+};
/* Values for `protoflag'. */
-#define GAI_PROTO_NOSERVICE 1
-#define GAI_PROTO_PROTOANY 2
-
-static const struct gaih_typeproto gaih_inet_typeproto[] =
-{
- { 0, 0, "", 0 },
- { SOCK_STREAM, IPPROTO_TCP, "tcp", 0 },
- { SOCK_DGRAM, IPPROTO_UDP, "udp", 0 },
- { SOCK_RAW, 0, "raw", GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE },
- { 0, 0, "", 0 }
+#define GAI_PROTO_NOSERVICE 1
+#define GAI_PROTO_PROTOANY 2
+
+static const struct gaih_typeproto gaih_inet_typeproto[] = {
+ { 0 , 0 , 0, "" },
+ { SOCK_STREAM, IPPROTO_TCP, 0, "tcp" },
+ { SOCK_DGRAM , IPPROTO_UDP, 0, "udp" },
+ { SOCK_RAW , 0 , GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, "raw" },
+ { 0 , 0 , 0, "" },
};
-struct gaih
-{
- int family;
- int (*gaih)(const char *name, const struct gaih_service *service,
- const struct addrinfo *req, struct addrinfo **pai);
+struct gaih {
+ int family;
+ int (*gaih)(const char *name, const struct gaih_service *service,
+ const struct addrinfo *req, struct addrinfo **pai);
};
-#if PF_UNSPEC == 0
-static const struct addrinfo default_hints;
-#else
-static const struct addrinfo default_hints =
-{ 0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL };
-#endif
-
#define SEEN_IPV4 1
#define SEEN_IPV6 2
-static unsigned __check_pf (void)
+static unsigned __check_pf(void)
{
- unsigned seen = 0;
+ unsigned seen = 0;
#if defined __UCLIBC_SUPPORT_AI_ADDRCONFIG__
- {
- /* Get the interface list via getifaddrs. */
- struct ifaddrs *ifa = NULL;
- struct ifaddrs *runp;
- if (getifaddrs (&ifa) != 0)
- {
- /* We cannot determine what interfaces are available. Be
- optimistic. */
+ {
+ /* Get the interface list via getifaddrs. */
+ struct ifaddrs *ifa = NULL;
+ struct ifaddrs *runp;
+ if (getifaddrs(&ifa) != 0) {
+ /* We cannot determine what interfaces are available.
+ * Be optimistic. */
#if defined __UCLIBC_HAS_IPV4__
- seen |= SEEN_IPV4;
+ seen |= SEEN_IPV4;
#endif /* __UCLIBC_HAS_IPV4__ */
#if defined __UCLIBC_HAS_IPV6__
- seen |= SEEN_IPV6;
+ seen |= SEEN_IPV6;
#endif /* __UCLIBC_HAS_IPV6__ */
- return seen;
- }
+ return seen;
+ }
- for (runp = ifa; runp != NULL; runp = runp->ifa_next)
+ for (runp = ifa; runp != NULL; runp = runp->ifa_next)
#if defined __UCLIBC_HAS_IPV4__
- if (runp->ifa_addr->sa_family == PF_INET)
- seen |= SEEN_IPV4;
+ if (runp->ifa_addr->sa_family == PF_INET)
+ seen |= SEEN_IPV4;
#endif /* __UCLIBC_HAS_IPV4__ */
-#if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__
- else /* can't be both at once */
-#endif /* __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__ */
#if defined __UCLIBC_HAS_IPV6__
- if (runp->ifa_addr->sa_family == PF_INET6)
- seen |= SEEN_IPV6;
+ if (runp->ifa_addr->sa_family == PF_INET6)
+ seen |= SEEN_IPV6;
#endif /* __UCLIBC_HAS_IPV6__ */
- (void) freeifaddrs (ifa);
- }
+ freeifaddrs(ifa);
+ }
#else
- /* AI_ADDRCONFIG is disabled, assume both ipv4 and ipv6 available. */
+ /* AI_ADDRCONFIG is disabled, assume both ipv4 and ipv6 available. */
#if defined __UCLIBC_HAS_IPV4__
- seen |= SEEN_IPV4;
+ seen |= SEEN_IPV4;
#endif /* __UCLIBC_HAS_IPV4__ */
#if defined __UCLIBC_HAS_IPV6__
- seen |= SEEN_IPV6;
+ seen |= SEEN_IPV6;
#endif /* __UCLIBC_HAS_IPV6__ */
#endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */
- return seen;
+ return seen;
}
-static int addrconfig (sa_family_t af)
+static int addrconfig(sa_family_t af)
{
- int s;
- int ret;
- int saved_errno = errno;
- unsigned seen;
+ int s;
+ int ret;
+ int saved_errno = errno;
+ unsigned seen;
- seen = __check_pf();
+ seen = __check_pf();
#if defined __UCLIBC_HAS_IPV4__
- if (af == AF_INET)
- ret = seen & SEEN_IPV4;
- else
+ if (af == AF_INET)
+ ret = seen & SEEN_IPV4;
+ else
#endif
#if defined __UCLIBC_HAS_IPV6__
- if (af == AF_INET6)
- ret = seen & SEEN_IPV6;
- else
+ if (af == AF_INET6)
+ ret = seen & SEEN_IPV6;
+ else
#endif
- {
- s = socket(af, SOCK_DGRAM, 0);
- ret = 1; /* Assume PF_UNIX. */
- if (s < 0) {
- if (errno != EMFILE)
- ret = 0;
+ {
+ s = socket(af, SOCK_DGRAM, 0);
+ ret = 1; /* Assume PF_UNIX. */
+ if (s < 0) {
+ if (errno != EMFILE)
+ ret = 0;
+ } else
+ close(s);
}
- else
- close(s);
- }
- __set_errno (saved_errno);
- return ret;
+ __set_errno(saved_errno);
+ return ret;
}
#if 0
/* Using Unix sockets this way is a security risk. */
static int
-gaih_local (const char *name, const struct gaih_service *service,
- const struct addrinfo *req, struct addrinfo **pai)
+gaih_local(const char *name, const struct gaih_service *service,
+ const struct addrinfo *req, struct addrinfo **pai)
{
- struct utsname utsname;
-
- if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST))
- return GAIH_OKIFUNSPEC | -EAI_NONAME;
-
- if ((name != NULL) || (req->ai_flags & AI_CANONNAME))
- if (uname (&utsname) < 0)
- return -EAI_SYSTEM;
-
- if (name != NULL)
- {
- if (strcmp(name, "localhost") &&
- strcmp(name, "local") &&
- strcmp(name, "unix") &&
- strcmp(name, utsname.nodename))
- return GAIH_OKIFUNSPEC | -EAI_NONAME;
- }
-
- if (req->ai_protocol || req->ai_socktype)
- {
- const struct gaih_typeproto *tp = gaih_inet_typeproto + 1;
-
- while (tp->name[0]
- && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0
- || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
- || (req->ai_protocol != 0
- && !(tp->protoflag & GAI_PROTO_PROTOANY)
- && req->ai_protocol != tp->protocol)))
- ++tp;
-
- if (! tp->name[0])
- {
- if (req->ai_socktype)
- return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
- else
- return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
- }
- }
-
- *pai = malloc (sizeof (struct addrinfo) + sizeof (struct sockaddr_un)
- + ((req->ai_flags & AI_CANONNAME)
- ? (strlen(utsname.nodename) + 1): 0));
- if (*pai == NULL)
- return -EAI_MEMORY;
-
- (*pai)->ai_next = NULL;
- (*pai)->ai_flags = req->ai_flags;
- (*pai)->ai_family = AF_LOCAL;
- (*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM;
- (*pai)->ai_protocol = req->ai_protocol;
- (*pai)->ai_addrlen = sizeof (struct sockaddr_un);
- (*pai)->ai_addr = (void *) (*pai) + sizeof (struct addrinfo);
+ struct utsname utsname;
+ struct addrinfo *ai = *pai;
+
+ if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST))
+ return (GAIH_OKIFUNSPEC | -EAI_NONAME);
+
+ if ((name != NULL) || (req->ai_flags & AI_CANONNAME))
+ if (uname(&utsname) < 0)
+ return -EAI_SYSTEM;
+
+ if (name != NULL) {
+ if (strcmp(name, "localhost") &&
+ strcmp(name, "local") &&
+ strcmp(name, "unix") &&
+ strcmp(name, utsname.nodename))
+ return (GAIH_OKIFUNSPEC | -EAI_NONAME);
+ }
+
+ if (req->ai_protocol || req->ai_socktype) {
+ const struct gaih_typeproto *tp = gaih_inet_typeproto + 1;
+
+ while (tp->name[0]
+ && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0
+ || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
+ || (req->ai_protocol != 0 && !(tp->protoflag & GAI_PROTO_PROTOANY) && req->ai_protocol != tp->protocol))
+ ) {
+ ++tp;
+ }
+ if (! tp->name[0]) {
+ if (req->ai_socktype)
+ return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
+ return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
+ }
+ }
+ *pai = ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_un)
+ + ((req->ai_flags & AI_CANONNAME)
+ ? (strlen(utsname.nodename) + 1) : 0));
+ if (ai == NULL)
+ return -EAI_MEMORY;
+
+ ai->ai_next = NULL;
+ ai->ai_flags = req->ai_flags;
+ ai->ai_family = AF_LOCAL;
+ ai->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM;
+ ai->ai_protocol = req->ai_protocol;
+ ai->ai_addrlen = sizeof(struct sockaddr_un);
+ ai->ai_addr = (void *)ai + sizeof(struct addrinfo);
#if SALEN
- ((struct sockaddr_un *) (*pai)->ai_addr)->sun_len =
- sizeof (struct sockaddr_un);
+ ((struct sockaddr_un *)ai->ai_addr)->sun_len = sizeof(struct sockaddr_un);
#endif /* SALEN */
- ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL;
- memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX);
+ ((struct sockaddr_un *)ai->ai_addr)->sun_family = AF_LOCAL;
+ memset(((struct sockaddr_un *)ai->ai_addr)->sun_path, 0, UNIX_PATH_MAX);
- if (service)
- {
- struct sockaddr_un *sunp = (struct sockaddr_un *) (*pai)->ai_addr;
+ if (service) {
+ struct sockaddr_un *sunp = (struct sockaddr_un *)ai->ai_addr;
- if (strchr (service->name, '/') != NULL)
- {
- if (strlen (service->name) >= sizeof (sunp->sun_path))
- return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+ if (strchr(service->name, '/') != NULL) {
+ if (strlen(service->name) >= sizeof(sunp->sun_path))
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
- strcpy (sunp->sun_path, service->name);
+ strcpy(sunp->sun_path, service->name);
+ } else {
+ if (strlen(P_tmpdir "/") + 1 + strlen(service->name) >= sizeof(sunp->sun_path))
+ return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
+ stpcpy(stpcpy(sunp->sun_path, P_tmpdir "/"), service->name);
+ }
+ } else {
+ /* This is a dangerous use of the interface since there is a time
+ window between the test for the file and the actual creation
+ (done by the caller) in which a file with the same name could
+ be created. */
+ char *buf = ((struct sockaddr_un *)ai->ai_addr)->sun_path;
+
+ if (__path_search(buf, L_tmpnam, NULL, NULL, 0) != 0
+ || __gen_tempname(buf, __GT_NOCREATE) != 0
+ ) {
+ return -EAI_SYSTEM;
+ }
}
- else
- {
- if (strlen (P_tmpdir "/") + 1 + strlen (service->name) >=
- sizeof (sunp->sun_path))
- return GAIH_OKIFUNSPEC | -EAI_SERVICE;
- stpcpy (stpcpy (sunp->sun_path, P_tmpdir "/"), service->name);
- }
- }
- else
- {
- /* This is a dangerous use of the interface since there is a time
- window between the test for the file and the actual creation
- (done by the caller) in which a file with the same name could
- be created. */
- char *buf = ((struct sockaddr_un *) (*pai)->ai_addr)->sun_path;
-
- if (__builtin_expect (__path_search (buf, L_tmpnam, NULL, NULL, 0),
- 0) != 0
- || __builtin_expect (__gen_tempname (buf, __GT_NOCREATE), 0) != 0)
- return -EAI_SYSTEM;
- }
-
- if (req->ai_flags & AI_CANONNAME)
- (*pai)->ai_canonname = strcpy ((char *) *pai + sizeof (struct addrinfo)
- + sizeof (struct sockaddr_un),
- utsname.nodename);
- else
- (*pai)->ai_canonname = NULL;
- return 0;
+ ai->ai_canonname = NULL;
+ if (req->ai_flags & AI_CANONNAME)
+ ai->ai_canonname = strcpy((char *)(ai + 1) + sizeof(struct sockaddr_un),
+ utsname.nodename);
+ return 0;
}
#endif /* 0 */
static int
-gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
+gaih_inet_serv(const char *servicename, const struct gaih_typeproto *tp,
const struct addrinfo *req, struct gaih_servtuple *st)
{
- struct servent *s;
- size_t tmpbuflen = 1024;
- struct servent ts;
- char *tmpbuf;
- int r;
-
- do
- {
- tmpbuf = alloca (tmpbuflen);
-
- r = getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
- &s);
- if (r != 0 || s == NULL)
- {
- if (r == ERANGE)
+ struct servent *s;
+ size_t tmpbuflen = 1024;
+ struct servent ts;
+ char *tmpbuf;
+ int r;
+
+ while (1) {
+ tmpbuf = alloca(tmpbuflen);
+ r = getservbyname_r(servicename, tp->name, &ts, tmpbuf, tmpbuflen, &s);
+ if (r == 0 && s != NULL)
+ break;
+ if (r != ERANGE)
+ return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
tmpbuflen *= 2;
- else
- return GAIH_OKIFUNSPEC | -EAI_SERVICE;
}
- }
- while (r);
-
- st->next = NULL;
- st->socktype = tp->socktype;
- st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
- ? req->ai_protocol : tp->protocol);
- st->port = s->s_port;
-
- return 0;
+ st->next = NULL;
+ st->socktype = tp->socktype;
+ st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) ? req->ai_protocol : tp->protocol);
+ st->port = s->s_port;
+ return 0;
}
-#define gethosts(_family, _type) \
-{ \
- int i, herrno; \
- size_t tmpbuflen; \
- struct hostent th; \
- char *tmpbuf; \
- tmpbuflen = 512; \
- no_data = 0; \
- do { \
- tmpbuflen *= 2; \
- tmpbuf = alloca (tmpbuflen); \
- rc = gethostbyname2_r (name, _family, &th, tmpbuf, \
- tmpbuflen, &h, &herrno); \
- } while (rc == ERANGE && herrno == NETDB_INTERNAL); \
- if (rc != 0) \
- { \
- if (herrno == NETDB_INTERNAL) \
- { \
- __set_h_errno (herrno); \
- return -EAI_SYSTEM; \
- } \
- if (herrno == TRY_AGAIN) \
- no_data = EAI_AGAIN; \
- else \
- no_data = herrno == NO_DATA; \
- } \
- else if (h != NULL) \
- { \
- for (i = 0; h->h_addr_list[i]; i++) \
- { \
- if (*pat == NULL) { \
- *pat = alloca (sizeof(struct gaih_addrtuple)); \
- (*pat)->scopeid = 0; \
- } \
- (*pat)->next = NULL; \
- (*pat)->family = _family; \
- memcpy ((*pat)->addr, h->h_addr_list[i], \
- sizeof(_type)); \
- pat = &((*pat)->next); \
- } \
- } \
+/* NB: also uses h,pat,rc,no_data variables */
+#define gethosts(_family, _type) \
+{ \
+ int i, herrno; \
+ size_t tmpbuflen; \
+ struct hostent th; \
+ char *tmpbuf; \
+ \
+ tmpbuflen = 512; \
+ no_data = 0; \
+ do { \
+ tmpbuflen *= 2; \
+ tmpbuf = alloca(tmpbuflen); \
+ rc = gethostbyname2_r(name, _family, &th, tmpbuf, \
+ tmpbuflen, &h, &herrno); \
+ } while (rc == ERANGE && herrno == NETDB_INTERNAL); \
+ if (rc != 0) { \
+ if (herrno == NETDB_INTERNAL) { \
+ __set_h_errno(herrno); \
+ return -EAI_SYSTEM; \
+ } \
+ if (herrno == TRY_AGAIN) \
+ no_data = EAI_AGAIN; \
+ else \
+ no_data = (herrno == NO_DATA); \
+ } else if (h != NULL) { \
+ for (i = 0; h->h_addr_list[i]; i++) { \
+ if (*pat == NULL) { \
+ *pat = alloca(sizeof(struct gaih_addrtuple)); \
+ (*pat)->scopeid = 0; \
+ } \
+ (*pat)->next = NULL; \
+ (*pat)->family = _family; \
+ memcpy((*pat)->addr, h->h_addr_list[i], sizeof(_type)); \
+ pat = &((*pat)->next); \
+ } \
+ } \
}
static int
-gaih_inet (const char *name, const struct gaih_service *service,
- const struct addrinfo *req, struct addrinfo **pai)
+gaih_inet(const char *name, const struct gaih_service *service,
+ const struct addrinfo *req, struct addrinfo **pai)
{
- const struct gaih_typeproto *tp = gaih_inet_typeproto;
- struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
- struct gaih_addrtuple *at = NULL;
- int rc;
- int v4mapped = (req->ai_family == PF_UNSPEC || req->ai_family == PF_INET6) &&
- (req->ai_flags & AI_V4MAPPED);
- unsigned seen = __check_pf();
-
- if (req->ai_protocol || req->ai_socktype)
- {
- ++tp;
-
- while (tp->name[0]
- && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
- || (req->ai_protocol != 0
- && !(tp->protoflag & GAI_PROTO_PROTOANY)
- && req->ai_protocol != tp->protocol)))
- ++tp;
-
- if (! tp->name[0])
- {
- if (req->ai_socktype)
- return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
- else
- return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
- }
- }
-
- if (service != NULL)
- {
- if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
- return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
-
- if (service->num < 0)
- {
- if (tp->name[0])
- {
- st = (struct gaih_servtuple *)
- alloca (sizeof (struct gaih_servtuple));
-
- if ((rc = gaih_inet_serv (service->name, tp, req, st)))
- return rc;
- }
- else
- {
- struct gaih_servtuple **pst = &st;
- for (tp++; tp->name[0]; tp++)
- {
- struct gaih_servtuple *newp;
-
- if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
- continue;
-
- if (req->ai_socktype != 0
- && req->ai_socktype != tp->socktype)
- continue;
- if (req->ai_protocol != 0
- && !(tp->protoflag & GAI_PROTO_PROTOANY)
- && req->ai_protocol != tp->protocol)
- continue;
-
- newp = (struct gaih_servtuple *)
- alloca (sizeof (struct gaih_servtuple));
-
- if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
- {
- if (rc & GAIH_OKIFUNSPEC)
- continue;
- return rc;
- }
-
- *pst = newp;
- pst = &(newp->next);
+ struct gaih_servtuple nullserv;
+
+ const struct gaih_typeproto *tp = gaih_inet_typeproto;
+ struct gaih_servtuple *st = &nullserv;
+ struct gaih_addrtuple *at = NULL;
+ int rc;
+ int v4mapped = (req->ai_family == PF_UNSPEC || req->ai_family == PF_INET6)
+ && (req->ai_flags & AI_V4MAPPED);
+ unsigned seen = __check_pf();
+
+ memset(&nullserv, 0, sizeof(nullserv));
+
+ if (req->ai_protocol || req->ai_socktype) {
+ ++tp;
+ while (tp->name[0]
+ && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
+ || (req->ai_protocol != 0 && !(tp->protoflag & GAI_PROTO_PROTOANY) && req->ai_protocol != tp->protocol)
+ )
+ ) {
+ ++tp;
+ }
+ if (! tp->name[0]) {
+ if (req->ai_socktype)
+ return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
+ return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
}
- if (st == (struct gaih_servtuple *) &nullserv)
- return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
- }
- }
- else
- {
- st = alloca (sizeof (struct gaih_servtuple));
- st->next = NULL;
- st->socktype = tp->socktype;
- st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
- ? req->ai_protocol : tp->protocol);
- st->port = htons (service->num);
}
- }
- else if (req->ai_socktype || req->ai_protocol)
- {
- st = alloca (sizeof (struct gaih_servtuple));
- st->next = NULL;
- st->socktype = tp->socktype;
- st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
- ? req->ai_protocol : tp->protocol);
- st->port = 0;
- }
- else
- {
- /*
- * Neither socket type nor protocol is set. Return all socket types
- * we know about.
- */
- struct gaih_servtuple **lastp = &st;
- for (++tp; tp->name[0]; ++tp)
- {
- struct gaih_servtuple *newp;
- newp = alloca (sizeof (struct gaih_servtuple));
- newp->next = NULL;
- newp->socktype = tp->socktype;
- newp->protocol = tp->protocol;
- newp->port = 0;
-
- *lastp = newp;
- lastp = &newp->next;
+ if (service != NULL) {
+ if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
+ return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
+
+ if (service->num < 0) {
+ if (tp->name[0]) {
+ st = alloca(sizeof(struct gaih_servtuple));
+ rc = gaih_inet_serv(service->name, tp, req, st);
+ if (rc)
+ return rc;
+ } else {
+ struct gaih_servtuple **pst = &st;
+ for (tp++; tp->name[0]; tp++) {
+ struct gaih_servtuple *newp;
+
+ if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
+ continue;
+
+ if (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
+ continue;
+ if (req->ai_protocol != 0
+ && !(tp->protoflag & GAI_PROTO_PROTOANY)
+ && req->ai_protocol != tp->protocol)
+ continue;
+
+ newp = alloca(sizeof(struct gaih_servtuple));
+ rc = gaih_inet_serv(service->name, tp, req, newp);
+ if (rc) {
+ if (rc & GAIH_OKIFUNSPEC)
+ continue;
+ return rc;
+ }
+
+ *pst = newp;
+ pst = &(newp->next);
+ }
+ if (st == &nullserv)
+ return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
+ }
+ } else {
+ st = alloca(sizeof(struct gaih_servtuple));
+ st->next = NULL;
+ st->socktype = tp->socktype;
+ st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
+ ? req->ai_protocol : tp->protocol);
+ st->port = htons(service->num);
+ }
+ } else if (req->ai_socktype || req->ai_protocol) {
+ st = alloca(sizeof(struct gaih_servtuple));
+ st->next = NULL;
+ st->socktype = tp->socktype;
+ st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
+ ? req->ai_protocol : tp->protocol);
+ st->port = 0;
+ } else {
+ /*
+ * Neither socket type nor protocol is set. Return all socket types
+ * we know about.
+ */
+ struct gaih_servtuple **lastp = &st;
+ for (++tp; tp->name[0]; ++tp) {
+ struct gaih_servtuple *newp;
+
+ newp = alloca(sizeof(struct gaih_servtuple));
+ newp->next = NULL;
+ newp->socktype = tp->socktype;
+ newp->protocol = tp->protocol;
+ newp->port = 0;
+
+ *lastp = newp;
+ lastp = &newp->next;
+ }
}
- }
-
- if (name != NULL)
- {
- at = alloca (sizeof (struct gaih_addrtuple));
- at->family = AF_UNSPEC;
- at->scopeid = 0;
- at->next = NULL;
-
- if (inet_pton (AF_INET, name, at->addr) > 0)
- {
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET || v4mapped)
- at->family = AF_INET;
- else
- return -EAI_FAMILY;
- }
+ if (name != NULL) {
+ at = alloca(sizeof(struct gaih_addrtuple));
+ at->family = AF_UNSPEC;
+ at->scopeid = 0;
+ at->next = NULL;
+
+ if (inet_pton(AF_INET, name, at->addr) > 0) {
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET || v4mapped)
+ at->family = AF_INET;
+ else
+ return -EAI_FAMILY;
+ }
#if defined __UCLIBC_HAS_IPV6__
- if (at->family == AF_UNSPEC)
- {
- char *namebuf = strdupa (name);
- char *scope_delim;
-
- scope_delim = strchr (namebuf, SCOPE_DELIMITER);
- if (scope_delim != NULL)
- *scope_delim = '\0';
-
- if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
- {
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
- at->family = AF_INET6;
- else
- return -EAI_FAMILY;
-
- if (scope_delim != NULL)
- {
- int try_numericscope = 0;
- if (IN6_IS_ADDR_LINKLOCAL (at->addr)
- || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
- {
- at->scopeid = if_nametoindex (scope_delim + 1);
- if (at->scopeid == 0)
- try_numericscope = 1;
- }
- else
- try_numericscope = 1;
-
- if (try_numericscope != 0)
- {
- char *end;
- assert (sizeof (uint32_t) <= sizeof (unsigned long));
- at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
- 10);
- if (*end != '\0')
- return GAIH_OKIFUNSPEC | -EAI_NONAME;
- }
+ if (at->family == AF_UNSPEC) {
+ char *namebuf = strdupa(name);
+ char *scope_delim;
+
+ scope_delim = strchr(namebuf, SCOPE_DELIMITER);
+ if (scope_delim != NULL)
+ *scope_delim = '\0';
+
+ if (inet_pton(AF_INET6, namebuf, at->addr) > 0) {
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
+ at->family = AF_INET6;
+ else
+ return -EAI_FAMILY;
+
+ if (scope_delim != NULL) {
+ int try_numericscope = 0;
+ if (IN6_IS_ADDR_LINKLOCAL(at->addr) || IN6_IS_ADDR_MC_LINKLOCAL(at->addr)) {
+ at->scopeid = if_nametoindex(scope_delim + 1);
+ if (at->scopeid == 0)
+ try_numericscope = 1;
+ } else
+ try_numericscope = 1;
+
+ if (try_numericscope != 0) {
+ char *end;
+ assert(sizeof(uint32_t) <= sizeof(unsigned long));
+ at->scopeid = (uint32_t)strtoul(scope_delim + 1, &end, 10);
+ if (*end != '\0')
+ return (GAIH_OKIFUNSPEC | -EAI_NONAME);
+ }
+ }
+ }
}
- }
- }
#endif
- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
- {
- struct hostent *h;
- struct gaih_addrtuple **pat = &at;
- int no_data = 0;
- int no_inet6_data;
-
- /*
- * If we are looking for both IPv4 and IPv6 address we don't want
- * the lookup functions to automatically promote IPv4 addresses to
- * IPv6 addresses.
- */
-
+ if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0) {
+ struct hostent *h;
+ struct gaih_addrtuple **pat = &at;
+ int no_data = 0;
+ int no_inet6_data;
+
+ /*
+ * If we are looking for both IPv4 and IPv6 address we don't want
+ * the lookup functions to automatically promote IPv4 addresses to
+ * IPv6 addresses.
+ */
#if defined __UCLIBC_HAS_IPV6__
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
- if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV6))
- gethosts (AF_INET6, struct in6_addr);
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
+ if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV6))
+ gethosts(AF_INET6, struct in6_addr);
#endif
- no_inet6_data = no_data;
-
- if (req->ai_family == AF_INET ||
- (!v4mapped && req->ai_family == AF_UNSPEC) ||
- (v4mapped && (no_inet6_data != 0 || (req->ai_flags & AI_ALL))))
- if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV4))
- gethosts (AF_INET, struct in_addr);
-
- if (no_data != 0 && no_inet6_data != 0)
- {
- /* If both requests timed out report this. */
- if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
- return -EAI_AGAIN;
-
- /*
- * We made requests but they turned out no data.
- * The name is known, though.
- */
- return (GAIH_OKIFUNSPEC | -EAI_AGAIN);
- }
- }
-
- if (at->family == AF_UNSPEC)
- return (GAIH_OKIFUNSPEC | -EAI_NONAME);
- }
- else
- {
- struct gaih_addrtuple *atr;
- atr = at = alloca (sizeof (struct gaih_addrtuple));
- memset (at, '\0', sizeof (struct gaih_addrtuple));
+ no_inet6_data = no_data;
+
+ if (req->ai_family == AF_INET
+ || (!v4mapped && req->ai_family == AF_UNSPEC)
+ || (v4mapped && (no_inet6_data != 0 || (req->ai_flags & AI_ALL)))
+ ) {
+ if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV4))
+ gethosts(AF_INET, struct in_addr);
+ }
+
+ if (no_data != 0 && no_inet6_data != 0) {
+ /* If both requests timed out report this. */
+ if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
+ return -EAI_AGAIN;
+ /*
+ * We made requests but they turned out no data.
+ * The name is known, though.
+ */
+ return (GAIH_OKIFUNSPEC | -EAI_AGAIN);
+ }
+ }
- if (req->ai_family == 0)
- {
- at->next = alloca (sizeof (struct gaih_addrtuple));
- memset (at->next, '\0', sizeof (struct gaih_addrtuple));
- }
+ if (at->family == AF_UNSPEC)
+ return (GAIH_OKIFUNSPEC | -EAI_NONAME);
+ } else {
+ struct gaih_addrtuple *atr;
+ atr = at = alloca(sizeof(struct gaih_addrtuple));
+ memset(at, '\0', sizeof(struct gaih_addrtuple));
+ if (req->ai_family == 0) {
+ at->next = alloca(sizeof(struct gaih_addrtuple));
+ memset(at->next, '\0', sizeof(struct gaih_addrtuple));
+ }
#if defined __UCLIBC_HAS_IPV6__
- if (req->ai_family == 0 || req->ai_family == AF_INET6)
- {
- at->family = AF_INET6;
- if ((req->ai_flags & AI_PASSIVE) == 0)
- memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
- atr = at->next;
- }
+ if (req->ai_family == 0 || req->ai_family == AF_INET6) {
+ at->family = AF_INET6;
+ if ((req->ai_flags & AI_PASSIVE) == 0)
+ memcpy(at->addr, &in6addr_loopback, sizeof(struct in6_addr));
+ atr = at->next;
+ }
#endif
-
- if (req->ai_family == 0 || req->ai_family == AF_INET)
- {
- atr->family = AF_INET;
- if ((req->ai_flags & AI_PASSIVE) == 0)
- *(uint32_t *) atr->addr = htonl (INADDR_LOOPBACK);
+ if (req->ai_family == 0 || req->ai_family == AF_INET) {
+ atr->family = AF_INET;
+ if ((req->ai_flags & AI_PASSIVE) == 0)
+ *(uint32_t*)atr->addr = htonl(INADDR_LOOPBACK);
+ }
}
- }
-
- if (pai == NULL)
- return 0;
-
- {
- const char *c = NULL;
- struct gaih_servtuple *st2;
- struct gaih_addrtuple *at2 = at;
- size_t socklen, namelen;
- sa_family_t family;
- /*
- * buffer is the size of an unformatted IPv6 address in
- * printable format.
- */
- char buffer[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+ if (pai == NULL)
+ return 0;
- while (at2 != NULL)
{
- if (req->ai_flags & AI_CANONNAME)
- {
- struct hostent *h = NULL;
-
- int herrno;
- struct hostent th;
- size_t tmpbuflen = 512;
- char *tmpbuf;
-
- do
- {
- tmpbuflen *= 2;
- tmpbuf = alloca (tmpbuflen);
-
- if (tmpbuf == NULL)
- return -EAI_MEMORY;
-
- rc = gethostbyaddr_r (at2->addr,
- ((at2->family == AF_INET6)
- ? sizeof(struct in6_addr)
- : sizeof(struct in_addr)),
- at2->family, &th, tmpbuf, tmpbuflen,
- &h, &herrno);
-
- }
- while (rc == errno && herrno == NETDB_INTERNAL);
-
- if (rc != 0 && herrno == NETDB_INTERNAL)
- {
- __set_h_errno (herrno);
- return -EAI_SYSTEM;
- }
-
- if (h == NULL)
- c = inet_ntop (at2->family, at2->addr, buffer, sizeof(buffer));
- else
- c = h->h_name;
+ const char *c = NULL;
+ struct gaih_servtuple *st2;
+ struct gaih_addrtuple *at2 = at;
+ size_t socklen, namelen;
+ sa_family_t family;
- if (c == NULL)
- return GAIH_OKIFUNSPEC | -EAI_NONAME;
-
- namelen = strlen (c) + 1;
- }
- else
- namelen = 0;
+ /*
+ * buffer is the size of an unformatted IPv6 address in
+ * printable format.
+ */
+ char buffer[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+
+ while (at2 != NULL) {
+ if (req->ai_flags & AI_CANONNAME) {
+ struct hostent *h = NULL;
+ int herrno;
+ struct hostent th;
+ size_t tmpbuflen = 512;
+ char *tmpbuf;
+
+ do {
+ tmpbuflen *= 2;
+ tmpbuf = alloca(tmpbuflen);
+ //if (tmpbuf == NULL)
+ // return -EAI_MEMORY;
+ rc = gethostbyaddr_r(at2->addr,
+ ((at2->family == AF_INET6)
+ ? sizeof(struct in6_addr)
+ : sizeof(struct in_addr)),
+ at2->family,
+ &th, tmpbuf, tmpbuflen,
+ &h, &herrno);
+ } while (rc == errno && herrno == NETDB_INTERNAL);
+
+ if (rc != 0 && herrno == NETDB_INTERNAL) {
+ __set_h_errno(herrno);
+ return -EAI_SYSTEM;
+ }
+
+ if (h == NULL)
+ c = inet_ntop(at2->family, at2->addr, buffer, sizeof(buffer));
+ else
+ c = h->h_name;
+
+ if (c == NULL)
+ return (GAIH_OKIFUNSPEC | -EAI_NONAME);
+
+ namelen = strlen(c) + 1;
+ } else
+ namelen = 0;
#if defined __UCLIBC_HAS_IPV6__
- if (at2->family == AF_INET6 || v4mapped)
- {
- family = AF_INET6;
- socklen = sizeof (struct sockaddr_in6);
- }
+ if (at2->family == AF_INET6 || v4mapped) {
+ family = AF_INET6;
+ socklen = sizeof(struct sockaddr_in6);
+ }
#endif
#if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__
- else
+ else
#endif
#if defined __UCLIBC_HAS_IPV4__
- {
- family = AF_INET;
- socklen = sizeof (struct sockaddr_in);
- }
+ {
+ family = AF_INET;
+ socklen = sizeof(struct sockaddr_in);
+ }
#endif
- for (st2 = st; st2 != NULL; st2 = st2->next)
- {
- if (req->ai_flags & AI_ADDRCONFIG) {
- if (family == AF_INET && !(seen & SEEN_IPV4))
- break;
+ for (st2 = st; st2 != NULL; st2 = st2->next) {
+ if (req->ai_flags & AI_ADDRCONFIG) {
+ if (family == AF_INET && !(seen & SEEN_IPV4))
+ break;
#if defined __UCLIBC_HAS_IPV6__
- else if (family == AF_INET6 && !(seen & SEEN_IPV6))
- break;
+ else if (family == AF_INET6 && !(seen & SEEN_IPV6))
+ break;
#endif
- }
- *pai = malloc (sizeof (struct addrinfo) + socklen + namelen);
- if (*pai == NULL)
- return -EAI_MEMORY;
-
- (*pai)->ai_flags = req->ai_flags;
- (*pai)->ai_family = family;
- (*pai)->ai_socktype = st2->socktype;
- (*pai)->ai_protocol = st2->protocol;
- (*pai)->ai_addrlen = socklen;
- (*pai)->ai_addr = (void *) (*pai) + sizeof(struct addrinfo);
+ }
+ *pai = malloc(sizeof(struct addrinfo) + socklen + namelen);
+ if (*pai == NULL)
+ return -EAI_MEMORY;
+
+ (*pai)->ai_flags = req->ai_flags;
+ (*pai)->ai_family = family;
+ (*pai)->ai_socktype = st2->socktype;
+ (*pai)->ai_protocol = st2->protocol;
+ (*pai)->ai_addrlen = socklen;
+ (*pai)->ai_addr = (void *) (*pai) + sizeof(struct addrinfo);
#if SALEN
- (*pai)->ai_addr->sa_len = socklen;
+ (*pai)->ai_addr->sa_len = socklen;
#endif /* SALEN */
- (*pai)->ai_addr->sa_family = family;
+ (*pai)->ai_addr->sa_family = family;
#if defined __UCLIBC_HAS_IPV6__
- if (family == AF_INET6)
- {
- struct sockaddr_in6 *sin6p =
- (struct sockaddr_in6 *) (*pai)->ai_addr;
-
- sin6p->sin6_flowinfo = 0;
- if (at2->family == AF_INET6)
- {
- memcpy (&sin6p->sin6_addr,
- at2->addr, sizeof (struct in6_addr));
- }
- else
- {
- sin6p->sin6_addr.s6_addr32[0] = 0;
- sin6p->sin6_addr.s6_addr32[1] = 0;
- sin6p->sin6_addr.s6_addr32[2] = htonl(0x0000ffff);
- memcpy(&sin6p->sin6_addr.s6_addr32[3],
- at2->addr, sizeof (sin6p->sin6_addr.s6_addr32[3]));
- }
- sin6p->sin6_port = st2->port;
- sin6p->sin6_scope_id = at2->scopeid;
- }
+ if (family == AF_INET6) {
+ struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) (*pai)->ai_addr;
+
+ sin6p->sin6_flowinfo = 0;
+ if (at2->family == AF_INET6) {
+ memcpy(&sin6p->sin6_addr,
+ at2->addr, sizeof(struct in6_addr));
+ } else {
+ sin6p->sin6_addr.s6_addr32[0] = 0;
+ sin6p->sin6_addr.s6_addr32[1] = 0;
+ sin6p->sin6_addr.s6_addr32[2] = htonl(0x0000ffff);
+ memcpy(&sin6p->sin6_addr.s6_addr32[3],
+ at2->addr, sizeof(sin6p->sin6_addr.s6_addr32[3]));
+ }
+ sin6p->sin6_port = st2->port;
+ sin6p->sin6_scope_id = at2->scopeid;
+ }
#endif
#if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__
- else
+ else
#endif
#if defined __UCLIBC_HAS_IPV4__
- {
- struct sockaddr_in *sinp =
- (struct sockaddr_in *) (*pai)->ai_addr;
-
- memcpy (&sinp->sin_addr,
- at2->addr, sizeof (struct in_addr));
- sinp->sin_port = st2->port;
- memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
- }
+ {
+ struct sockaddr_in *sinp = (struct sockaddr_in *) (*pai)->ai_addr;
+
+ memcpy(&sinp->sin_addr, at2->addr, sizeof(struct in_addr));
+ sinp->sin_port = st2->port;
+ memset(sinp->sin_zero, '\0', sizeof(sinp->sin_zero));
+ }
#endif
- if (c)
- {
- (*pai)->ai_canonname = ((void *) (*pai) +
- sizeof (struct addrinfo) + socklen);
- strcpy ((*pai)->ai_canonname, c);
+ if (c) {
+ (*pai)->ai_canonname = ((void *) (*pai) +
+ sizeof(struct addrinfo) + socklen);
+ strcpy((*pai)->ai_canonname, c);
+ } else {
+ (*pai)->ai_canonname = NULL;
+ }
+ (*pai)->ai_next = NULL;
+ pai = &((*pai)->ai_next);
+ }
+
+ at2 = at2->next;
}
- else
- (*pai)->ai_canonname = NULL;
-
- (*pai)->ai_next = NULL;
- pai = &((*pai)->ai_next);
- }
-
- at2 = at2->next;
}
- }
- return 0;
+ return 0;
}
-static struct gaih gaih[] =
-{
+static const struct gaih gaih[] = {
#if defined __UCLIBC_HAS_IPV6__
- { PF_INET6, gaih_inet },
+ { PF_INET6, gaih_inet },
#endif
- { PF_INET, gaih_inet },
+ { PF_INET, gaih_inet },
#if 0
- { PF_LOCAL, gaih_local },
+ { PF_LOCAL, gaih_local },
#endif
- { PF_UNSPEC, NULL }
+ { PF_UNSPEC, NULL }
};
libc_hidden_proto(freeaddrinfo)
void
-freeaddrinfo (struct addrinfo *ai)
+freeaddrinfo(struct addrinfo *ai)
{
- struct addrinfo *p;
-
- while (ai != NULL)
- {
- p = ai;
- ai = ai->ai_next;
- free (p);
- }
+ struct addrinfo *p;
+
+ while (ai != NULL) {
+ p = ai;
+ ai = ai->ai_next;
+ free(p);
+ }
}
libc_hidden_def(freeaddrinfo)
libc_hidden_proto(getaddrinfo)
int
-getaddrinfo (const char *name, const char *service,
+getaddrinfo(const char *name, const char *service,
const struct addrinfo *hints, struct addrinfo **pai)
{
- int i = 0, j = 0, last_i = 0;
- struct addrinfo *p = NULL, **end;
- struct gaih *g = gaih, *pg = NULL;
- struct gaih_service gaih_service, *pservice;
-
- if (name != NULL && name[0] == '*' && name[1] == 0)
- name = NULL;
-
- if (service != NULL && service[0] == '*' && service[1] == 0)
- service = NULL;
-
- if (name == NULL && service == NULL)
- return EAI_NONAME;
-
- if (hints == NULL)
- hints = &default_hints;
-
- if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|
- AI_ADDRCONFIG|AI_V4MAPPED|AI_NUMERICSERV|AI_ALL))
- return EAI_BADFLAGS;
-
- if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
- return EAI_BADFLAGS;
+ int i = 0, j, last_i = 0;
+ struct addrinfo *p = NULL, **end;
+ const struct gaih *g = gaih, *pg = NULL;
+ struct gaih_service gaih_service, *pservice;
+ struct addrinfo default_hints;
+
+ if (name != NULL && name[0] == '*' && name[1] == 0)
+ name = NULL;
+
+ if (service != NULL && service[0] == '*' && service[1] == 0)
+ service = NULL;
+
+ if (name == NULL && service == NULL)
+ return EAI_NONAME;
+
+ if (hints == NULL) {
+ memset(&default_hints, 0, sizeof(default_hints));
+ if (AF_UNSPEC)
+ default_hints.ai_family = AF_UNSPEC;
+ hints = &default_hints;
+ }
- if (service && service[0])
- {
- char *c;
- gaih_service.name = service;
- gaih_service.num = strtoul (gaih_service.name, &c, 10);
- if (*c != '\0') {
- if (hints->ai_flags & AI_NUMERICSERV)
- return EAI_NONAME;
+ if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|
+ AI_ADDRCONFIG|AI_V4MAPPED|AI_NUMERICSERV|AI_ALL))
+ return EAI_BADFLAGS;
+
+ if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
+ return EAI_BADFLAGS;
+
+ if (service && service[0]) {
+ char *c;
+ gaih_service.name = service;
+ gaih_service.num = strtoul(gaih_service.name, &c, 10);
+ if (*c != '\0') {
+ if (hints->ai_flags & AI_NUMERICSERV)
+ return EAI_NONAME;
+ gaih_service.num = -1;
+ } else {
+ /*
+ * Can't specify a numerical socket unless a protocol
+ * family was given.
+ */
+ if (hints->ai_socktype == 0 && hints->ai_protocol == 0)
+ return EAI_SERVICE;
+ }
+ pservice = &gaih_service;
+ } else
+ pservice = NULL;
- gaih_service.num = -1;
- }
- else
- /*
- * Can't specify a numerical socket unless a protocol
- * family was given.
- */
- if (hints->ai_socktype == 0 && hints->ai_protocol == 0)
- return EAI_SERVICE;
- pservice = &gaih_service;
- }
- else
- pservice = NULL;
-
- if (pai)
- end = &p;
- else
end = NULL;
-
- while (g->gaih)
- {
- if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC)
- {
- if ((hints->ai_flags & AI_ADDRCONFIG) && !addrconfig(g->family))
- {
- ++g;
- continue;
- }
- j++;
- if (pg == NULL || pg->gaih != g->gaih)
- {
- pg = g;
- i = g->gaih (name, pservice, hints, end);
- if (i != 0)
- {
- last_i = i;
-
- if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC))
- continue;
-
- if (p)
- freeaddrinfo (p);
-
- return -(i & GAIH_EAI);
+ if (pai)
+ end = &p;
+
+ j = 0;
+ while (g->gaih) {
+ if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC) {
+ if ((hints->ai_flags & AI_ADDRCONFIG) && !addrconfig(g->family)) {
+ ++g;
+ continue;
+ }
+ j++;
+ if (pg == NULL || pg->gaih != g->gaih) {
+ pg = g;
+ i = g->gaih(name, pservice, hints, end);
+ if (i != 0) {
+ last_i = i;
+ if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC))
+ continue;
+ if (p)
+ freeaddrinfo(p);
+ return -(i & GAIH_EAI);
+ }
+ if (end)
+ while (*end)
+ end = &((*end)->ai_next);
+ }
}
- if (end)
- while(*end) end = &((*end)->ai_next);
- }
+ ++g;
}
- ++g;
- }
- if (j == 0)
- return EAI_FAMILY;
+ if (j == 0)
+ return EAI_FAMILY;
- if (p)
- {
- *pai = p;
- return 0;
- }
+ if (p) {
+ *pai = p;
+ return 0;
+ }
- if (pai == NULL && last_i == 0)
- return 0;
+ if (pai == NULL && last_i == 0)
+ return 0;
- if (p)
- freeaddrinfo (p);
+ /* if (p) - never happens, see above */
+ /* freeaddrinfo(p); */
- return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
+ return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
}
libc_hidden_def(getaddrinfo)
diff --git a/libc/inet/resolvename.c b/libc/inet/gethostent_r.c
index 157878fd1..aeade155d 100644
--- a/libc/inet/resolvename.c
+++ b/libc/inet/gethostent_r.c
@@ -4,5 +4,5 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_resolvename
+#define L_gethostent_r
#include "resolv.c"
diff --git a/libc/inet/herror.c b/libc/inet/herror.c
index 063f6e93e..b46578388 100644
--- a/libc/inet/herror.c
+++ b/libc/inet/herror.c
@@ -26,7 +26,7 @@
libc_hidden_proto(fprintf)
libc_hidden_proto(__h_errno_location)
-static const char *error_msg = "Resolver error";
+static const char error_msg[] = "Resolver error";
static const char *const h_errlist[] = {
"Error 0",
"Unknown host", /* 1 HOST_NOT_FOUND */
@@ -52,7 +52,7 @@ void herror(const char *s)
}
p = error_msg;
if ((h_errno >= 0) && (h_errno < h_nerr)) {
- p = h_errlist[h_errno];
+ p = h_errlist[h_errno];
}
fprintf(stderr, "%s%s%s\n", s, c, p);
}
@@ -61,10 +61,8 @@ libc_hidden_def(herror)
const char *hstrerror(int err)
{
- if (err < 0) {
- return(error_msg);
- } else if (err < h_nerr) {
- return(h_errlist[err]);
- }
- return(error_msg);
+ if ((unsigned)err < h_nerr)
+ return(h_errlist[err]);
+
+ return error_msg;
}
diff --git a/libc/inet/hostid.c b/libc/inet/hostid.c
index 33668a2fe..2528a8ce6 100644
--- a/libc/inet/hostid.c
+++ b/libc/inet/hostid.c
@@ -25,7 +25,7 @@ libc_hidden_proto(read)
libc_hidden_proto(write)
libc_hidden_proto(getuid)
libc_hidden_proto(geteuid)
-libc_hidden_proto(gethostbyname)
+libc_hidden_proto(gethostbyname_r)
libc_hidden_proto(gethostname)
#define HOSTID "/etc/hostid"
diff --git a/libc/inet/ifaddrs.c b/libc/inet/ifaddrs.c
index a96b19a54..46be5f6b5 100644
--- a/libc/inet/ifaddrs.c
+++ b/libc/inet/ifaddrs.c
@@ -22,7 +22,7 @@
#include <alloca.h>
#include <assert.h>
#include <errno.h>
-#include "ifaddrs.h"
+#include <ifaddrs.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netpacket/packet.h>
@@ -308,9 +308,6 @@ __netlink_open (struct netlink_handle *h)
close_and_out:
__netlink_close (h);
out:
-#if __ASSUME_NETLINK_SUPPORT == 0
- __no_netlink_support = 1;
-#endif
return -1;
}
/* Determine the ID the kernel assigned for this netlink connection.
@@ -333,7 +330,7 @@ __netlink_open (struct netlink_handle *h)
that a RTM_NEWADDR index is not known to this map. */
static int
internal_function
-map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max)
+map_newlink (int idx, struct ifaddrs_storage *ifas, int *map, int max)
{
int i;
@@ -341,12 +338,12 @@ map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max)
{
if (map[i] == -1)
{
- map[i] = index;
+ map[i] = idx;
if (i > 0)
ifas[i - 1].ifa.ifa_next = &ifas[i].ifa;
return i;
}
- else if (map[i] == index)
+ else if (map[i] == idx)
return i;
}
/* This should never be reached. If this will be reached, we have
@@ -374,18 +371,11 @@ getifaddrs (struct ifaddrs **ifap)
if (ifap)
*ifap = NULL;
- if (! __no_netlink_support && __netlink_open (&nh) < 0)
+ if (__netlink_open (&nh) < 0)
{
-#if __ASSUME_NETLINK_SUPPORT != 0
return -1;
-#endif
}
-#if __ASSUME_NETLINK_SUPPORT == 0
- if (__no_netlink_support)
- return fallback_getifaddrs (ifap);
-#endif
-
/* Tell the kernel that we wish to get a list of all
active interfaces, collect all data for every interface. */
if (__netlink_request (&nh, RTM_GETLINK) < 0)
@@ -864,13 +854,11 @@ getifaddrs (struct ifaddrs **ifap)
}
-#if __ASSUME_NETLINK_SUPPORT != 0
void
freeifaddrs (struct ifaddrs *ifa)
{
free (ifa);
}
-#endif
#endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */
diff --git a/libc/inet/ifaddrs.h b/libc/inet/ifaddrs.h
deleted file mode 100644
index f65bcaba3..000000000
--- a/libc/inet/ifaddrs.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* ifaddrs.h -- declarations for getting network interface addresses
- Copyright (C) 2002 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#ifndef _IFADDRS_H
-#define _IFADDRS_H 1
-
-#include <features.h>
-#include <sys/socket.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-__BEGIN_DECLS
-
-/* The `getifaddrs' function generates a linked list of these structures.
- Each element of the list describes one network interface. */
-struct ifaddrs
-{
- struct ifaddrs *ifa_next; /* Pointer to the next structure. */
-
- char *ifa_name; /* Name of this network interface. */
- unsigned int ifa_flags; /* Flags as from SIOCGIFFLAGS ioctl. */
-
- struct sockaddr *ifa_addr; /* Network address of this interface. */
- struct sockaddr *ifa_netmask; /* Netmask of this interface. */
- union
- {
- /* At most one of the following two is valid. If the IFF_BROADCAST
- bit is set in `ifa_flags', then `ifa_broadaddr' is valid. If the
- IFF_POINTOPOINT bit is set, then `ifa_dstaddr' is valid.
- It is never the case that both these bits are set at once. */
- struct sockaddr *ifu_broadaddr; /* Broadcast address of this interface. */
- struct sockaddr *ifu_dstaddr; /* Point-to-point destination address. */
- } ifa_ifu;
- /* These very same macros are defined by <net/if.h> for `struct ifaddr'.
- So if they are defined already, the existing definitions will be fine. */
-# ifndef ifa_broadaddr
-# define ifa_broadaddr ifa_ifu.ifu_broadaddr
-# endif
-# ifndef ifa_dstaddr
-# define ifa_dstaddr ifa_ifu.ifu_dstaddr
-# endif
-
- void *ifa_data; /* Address-specific data (may be unused). */
-};
-
-
-/* Create a linked list of `struct ifaddrs' structures, one for each
- network interface on the host machine. If successful, store the
- list in *IFAP and return 0. On errors, return -1 and set `errno'.
-
- The storage returned in *IFAP is allocated dynamically and can
- only be properly freed by passing it to `freeifaddrs'. */
-extern int getifaddrs (struct ifaddrs **__ifap) __THROW;
-
-/* Reclaim the storage allocated by a previous `getifaddrs' call. */
-extern void freeifaddrs (struct ifaddrs *__ifa) __THROW;
-
-__END_DECLS
-
-#endif /* ifaddrs.h */
diff --git a/libc/inet/netlinkaccess.h b/libc/inet/netlinkaccess.h
index acadcb544..5111d3802 100644
--- a/libc/inet/netlinkaccess.h
+++ b/libc/inet/netlinkaccess.h
@@ -24,6 +24,7 @@
#include <unistd.h>
#include <sys/types.h>
+#if defined __ASSUME_NETLINK_SUPPORT || defined __UCLIBC_USE_NETLINK__
#define _LINUX_TYPES_H
typedef uint8_t __u8;
typedef uint16_t __u16;
@@ -33,16 +34,6 @@ typedef int32_t __s32;
#include <linux/rtnetlink.h>
#include <linux/netlink.h>
-/* Should prob be a configure option or something */
-#ifndef __ASSUME_NETLINK_SUPPORT
-#ifdef __UCLIBC_USE_NETLINK__
-# define __ASSUME_NETLINK_SUPPORT 1
-#else
-# define __ASSUME_NETLINK_SUPPORT 0
-#endif
-#endif
-
-
struct netlink_res
{
struct netlink_res *next;
@@ -62,19 +53,17 @@ struct netlink_handle
};
-#ifdef __UCLIBC_SUPPORT_AI_ADDRCONFIG__
-#if __ASSUME_NETLINK_SUPPORT == 0
-extern smallint __no_netlink_support attribute_hidden;
-#else
-# define __no_netlink_support 0
+#ifndef __ASSUME_NETLINK_SUPPORT
+#define __ASSUME_NETLINK_SUPPORT 1
#endif
-#endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */
-
extern int __netlink_open (struct netlink_handle *h) attribute_hidden;
extern void __netlink_close (struct netlink_handle *h) attribute_hidden;
extern void __netlink_free_handle (struct netlink_handle *h) attribute_hidden;
extern int __netlink_request (struct netlink_handle *h, int type) attribute_hidden;
+#else
+#define __ASSUME_NETLINK_SUPPORT 0
+#endif
-#endif /* netlinkaccess.h */
+#endif /* _NETLINKACCESS_H */
diff --git a/libc/inet/rpc/rpc_thread.c b/libc/inet/rpc/rpc_thread.c
index 5b6579e14..441aa75a8 100644
--- a/libc/inet/rpc/rpc_thread.c
+++ b/libc/inet/rpc/rpc_thread.c
@@ -35,7 +35,7 @@ __rpc_thread_destroy (void)
if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem) {
__rpc_thread_svc_cleanup ();
__rpc_thread_clnt_cleanup ();
- //__rpc_thread_key_cleanup ();
+ /*__rpc_thread_key_cleanup (); */
free (tvp->authnone_private_s);
free (tvp->clnt_perr_buf_s);
free (tvp->clntraw_private_s);
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c
index 9211b01ce..66cf8f865 100644
--- a/libc/inet/socketcalls.c
+++ b/libc/inet/socketcalls.c
@@ -44,7 +44,7 @@ extern int __socketcall(int call, unsigned long *args) attribute_hidden;
extern __typeof(accept) __libc_accept;
#ifdef __NR_accept
#define __NR___libc_accept __NR_accept
-_syscall3(int, __libc_accept, int, call, struct sockaddr *, addr, socklen_t *,addrlen);
+_syscall3(int, __libc_accept, int, call, struct sockaddr *, addr, socklen_t *,addrlen)
#elif defined(__NR_socketcall)
int __libc_accept(int s, struct sockaddr *addr, socklen_t * addrlen)
{
@@ -74,7 +74,7 @@ libc_hidden_weak(accept)
#ifdef L_bind
libc_hidden_proto(bind)
#ifdef __NR_bind
-_syscall3(int, bind, int, sockfd, const struct sockaddr *, myaddr, socklen_t, addrlen);
+_syscall3(int, bind, int, sockfd, const struct sockaddr *, myaddr, socklen_t, addrlen)
#elif defined(__NR_socketcall)
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
{
@@ -93,7 +93,7 @@ libc_hidden_def(bind)
extern __typeof(connect) __libc_connect;
#ifdef __NR_connect
#define __NR___libc_connect __NR_connect
-_syscall3(int, __libc_connect, int, sockfd, const struct sockaddr *, saddr, socklen_t, addrlen);
+_syscall3(int, __libc_connect, int, sockfd, const struct sockaddr *, saddr, socklen_t, addrlen)
#elif defined(__NR_socketcall)
int __libc_connect(int sockfd, const struct sockaddr *saddr, socklen_t addrlen)
{
@@ -121,7 +121,7 @@ libc_hidden_weak(connect)
#ifdef L_getpeername
#ifdef __NR_getpeername
-_syscall3(int, getpeername, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen);
+_syscall3(int, getpeername, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen)
#elif defined(__NR_socketcall)
int getpeername(int sockfd, struct sockaddr *addr, socklen_t * paddrlen)
{
@@ -138,7 +138,7 @@ int getpeername(int sockfd, struct sockaddr *addr, socklen_t * paddrlen)
#ifdef L_getsockname
libc_hidden_proto(getsockname)
#ifdef __NR_getsockname
-_syscall3(int, getsockname, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen);
+_syscall3(int, getsockname, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen)
#elif defined(__NR_socketcall)
int getsockname(int sockfd, struct sockaddr *addr, socklen_t * paddrlen)
{
@@ -155,7 +155,7 @@ libc_hidden_def(getsockname)
#ifdef L_getsockopt
#ifdef __NR_getsockopt
-_syscall5(int, getsockopt, int, fd, int, level, int, optname, __ptr_t, optval, socklen_t *, optlen);
+_syscall5(int, getsockopt, int, fd, int, level, int, optname, __ptr_t, optval, socklen_t *, optlen)
#elif defined(__NR_socketcall)
int getsockopt(int fd, int level, int optname, __ptr_t optval,
socklen_t * optlen)
@@ -175,7 +175,7 @@ int getsockopt(int fd, int level, int optname, __ptr_t optval,
#ifdef L_listen
libc_hidden_proto(listen)
#ifdef __NR_listen
-_syscall2(int, listen, int, sockfd, int, backlog);
+_syscall2(int, listen, int, sockfd, int, backlog)
#elif defined(__NR_socketcall)
int listen(int sockfd, int backlog)
{
@@ -194,7 +194,7 @@ extern __typeof(recv) __libc_recv;
#ifdef __NR_recv
#define __NR___libc_recv __NR_recv
_syscall4(ssize_t, __libc_recv, int, sockfd, __ptr_t, buffer, size_t, len,
- int, flags);
+ int, flags)
#elif defined(__NR_socketcall)
/* recv, recvfrom added by bir7@leland.stanford.edu */
ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags)
@@ -233,7 +233,7 @@ extern __typeof(recvfrom) __libc_recvfrom;
#ifdef __NR_recvfrom
#define __NR___libc_recvfrom __NR_recvfrom
_syscall6(ssize_t, __libc_recvfrom, int, sockfd, __ptr_t, buffer, size_t, len,
- int, flags, struct sockaddr *, to, socklen_t *, tolen);
+ int, flags, struct sockaddr *, to, socklen_t *, tolen)
#elif defined(__NR_socketcall)
/* recv, recvfrom added by bir7@leland.stanford.edu */
ssize_t __libc_recvfrom(int sockfd, __ptr_t buffer, size_t len, int flags,
@@ -268,7 +268,7 @@ libc_hidden_weak(recvfrom)
extern __typeof(recvmsg) __libc_recvmsg;
#ifdef __NR_recvmsg
#define __NR___libc_recvmsg __NR_recvmsg
-_syscall3(ssize_t, __libc_recvmsg, int, sockfd, struct msghdr *, msg, int, flags);
+_syscall3(ssize_t, __libc_recvmsg, int, sockfd, struct msghdr *, msg, int, flags)
#elif defined(__NR_socketcall)
ssize_t __libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
{
@@ -298,7 +298,7 @@ libc_hidden_weak(recvmsg)
extern __typeof(send) __libc_send;
#ifdef __NR_send
#define __NR___libc_send __NR_send
-_syscall4(ssize_t, __libc_send, int, sockfd, const void *, buffer, size_t, len, int, flags);
+_syscall4(ssize_t, __libc_send, int, sockfd, const void *, buffer, size_t, len, int, flags)
#elif defined(__NR_socketcall)
/* send, sendto added by bir7@leland.stanford.edu */
ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags)
@@ -336,7 +336,7 @@ libc_hidden_weak(send)
extern __typeof(sendmsg) __libc_sendmsg;
#ifdef __NR_sendmsg
#define __NR___libc_sendmsg __NR_sendmsg
-_syscall3(ssize_t, __libc_sendmsg, int, sockfd, const struct msghdr *, msg, int, flags);
+_syscall3(ssize_t, __libc_sendmsg, int, sockfd, const struct msghdr *, msg, int, flags)
#elif defined(__NR_socketcall)
ssize_t __libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
{
@@ -367,7 +367,7 @@ extern __typeof(sendto) __libc_sendto;
#ifdef __NR_sendto
#define __NR___libc_sendto __NR_sendto
_syscall6(ssize_t, __libc_sendto, int, sockfd, const void *, buffer,
- size_t, len, int, flags, const struct sockaddr *, to, socklen_t, tolen);
+ size_t, len, int, flags, const struct sockaddr *, to, socklen_t, tolen)
#elif defined(__NR_socketcall)
/* send, sendto added by bir7@leland.stanford.edu */
ssize_t __libc_sendto(int sockfd, const void *buffer, size_t len, int flags,
@@ -401,7 +401,7 @@ libc_hidden_weak(sendto)
#ifdef L_setsockopt
libc_hidden_proto(setsockopt)
#ifdef __NR_setsockopt
-_syscall5(int, setsockopt, int, fd, int, level, int, optname, const void *, optval, socklen_t, optlen);
+_syscall5(int, setsockopt, int, fd, int, level, int, optname, const void *, optval, socklen_t, optlen)
#elif defined(__NR_socketcall)
/* [sg]etsockoptions by bir7@leland.stanford.edu */
int setsockopt(int fd, int level, int optname, const void *optval,
@@ -422,7 +422,7 @@ libc_hidden_def(setsockopt)
#ifdef L_shutdown
#ifdef __NR_shutdown
-_syscall2(int, shutdown, int, sockfd, int, how);
+_syscall2(int, shutdown, int, sockfd, int, how)
#elif defined(__NR_socketcall)
/* shutdown by bir7@leland.stanford.edu */
int shutdown(int sockfd, int how)
@@ -439,7 +439,7 @@ int shutdown(int sockfd, int how)
#ifdef L_socket
libc_hidden_proto(socket)
#ifdef __NR_socket
-_syscall3(int, socket, int, family, int, type, int, protocol);
+_syscall3(int, socket, int, family, int, type, int, protocol)
#elif defined(__NR_socketcall)
int socket(int family, int type, int protocol)
{
@@ -456,7 +456,7 @@ libc_hidden_def(socket)
#ifdef L_socketpair
#ifdef __NR_socketpair
-_syscall4(int, socketpair, int, family, int, type, int, protocol, int *, sockvec);
+_syscall4(int, socketpair, int, family, int, type, int, protocol, int *, sockvec)
#elif defined(__NR_socketcall)
int socketpair(int family, int type, int protocol, int sockvec[2])
{
diff --git a/libc/pwd_grp/__getgrouplist_internal.c b/libc/pwd_grp/__getgrouplist_internal.c
new file mode 100644
index 000000000..c2edc99cf
--- /dev/null
+++ b/libc/pwd_grp/__getgrouplist_internal.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___getgrouplist_internal
+#include "pwd_grp.c"
diff --git a/libc/inet/resolveaddress.c b/libc/pwd_grp/getgrouplist.c
index d57366c98..a4eba7dbb 100644
--- a/libc/inet/resolveaddress.c
+++ b/libc/pwd_grp/getgrouplist.c
@@ -4,5 +4,5 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_resolveaddress
-#include "resolv.c"
+#define L_getgrouplist
+#include "pwd_grp.c"
diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c
index 217ed39a7..5af1f0c15 100644
--- a/libc/pwd_grp/pwd_grp.c
+++ b/libc/pwd_grp/pwd_grp.c
@@ -64,6 +64,8 @@ extern int __parsespent(void *sp, char *line) attribute_hidden;
extern int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data,
char *__restrict line_buff, size_t buflen, FILE *f) attribute_hidden;
+extern gid_t* __getgrouplist_internal(const char *user, gid_t gid, int *ngroups) attribute_hidden;
+
/**********************************************************************/
/* For the various fget??ent_r funcs, return
*
@@ -684,62 +686,105 @@ struct spwd *sgetspent(const char *string)
#endif
/**********************************************************************/
-#ifdef L_initgroups
+#ifdef L___getgrouplist_internal
-#ifdef __USE_BSD
-
-libc_hidden_proto(setgroups)
-
-int initgroups(const char *user, gid_t gid)
+gid_t attribute_hidden *__getgrouplist_internal(const char *user, gid_t gid, int *ngroups)
{
FILE *grfile;
gid_t *group_list;
- int num_groups, rv;
- char **m;
+ int num_groups;
struct group group;
char buff[__UCLIBC_PWD_BUFFER_SIZE__];
- rv = -1;
+ *ngroups = num_groups = 1;
/* We alloc space for 8 gids at a time. */
- if (((group_list = (gid_t *) malloc(8*sizeof(gid_t *))) != NULL)
- && ((grfile = fopen(_PATH_GROUP, "r")) != NULL)
- ) {
-
- __STDIO_SET_USER_LOCKING(grfile);
-
- *group_list = gid;
- num_groups = 1;
-
- while (!__pgsreader(__parsegrent, &group, buff, sizeof(buff), grfile)) {
- assert(group.gr_mem); /* Must have at least a NULL terminator. */
- if (group.gr_gid != gid) {
- for (m=group.gr_mem ; *m ; m++) {
- if (!strcmp(*m, user)) {
- if (!(num_groups & 7)) {
- gid_t *tmp = (gid_t *)
- realloc(group_list,
- (num_groups+8) * sizeof(gid_t *));
- if (!tmp) {
- rv = -1;
- goto DO_CLOSE;
- }
- group_list = tmp;
- }
- group_list[num_groups++] = group.gr_gid;
- break;
- }
- }
+ group_list = malloc(8 * sizeof(group_list[0]));
+ if (!group_list)
+ return NULL;
+
+ group_list[0] = gid;
+ grfile = fopen(_PATH_GROUP, "r");
+ /* If /etc/group doesn't exist, we still return 1-element vector */
+ if (!grfile)
+ return group_list;
+
+ __STDIO_SET_USER_LOCKING(grfile);
+
+ while (!__pgsreader(__parsegrent, &group, buff, sizeof(buff), grfile)) {
+ char **m;
+
+ assert(group.gr_mem); /* Must have at least a NULL terminator. */
+ if (group.gr_gid == gid)
+ continue;
+ for (m = group.gr_mem; *m; m++) {
+ if (strcmp(*m, user) != 0)
+ continue;
+ if (!(num_groups & 7)) {
+ gid_t *tmp = realloc(group_list, (num_groups+8) * sizeof(group_list[0]));
+ if (!tmp)
+ goto DO_CLOSE;
+ group_list = tmp;
}
+ group_list[num_groups++] = group.gr_gid;
+ break;
}
+ }
+
+ DO_CLOSE:
+ fclose(grfile);
+ *ngroups = num_groups;
+ return group_list;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_getgrouplist
- rv = setgroups(num_groups, group_list);
- DO_CLOSE:
- fclose(grfile);
+#if defined __USE_BSD || defined __USE_GNU
+int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
+{
+ int sz = *ngroups;
+ gid_t *group_list = __getgrouplist_internal(user, gid, ngroups);
+
+ if (!group_list) {
+ /* malloc failure - what shall we do?
+ * fail with ENOMEM? I bet users never check for that */
+ /* *ngroups = 1; - already done by __getgrouplist_internal */
+ if (sz) {
+ groups[0] = gid;
+ return 1;
+ }
+ return -1;
}
+ /* *ngroups is non-zero here */
+
+ if (sz > *ngroups)
+ sz = *ngroups;
+ if (sz)
+ memcpy(groups, group_list, sz * sizeof(group_list[0]));
+ free(group_list);
+ if (sz < *ngroups)
+ return -1;
+ return sz;
+}
+#endif
+
+#endif
+/**********************************************************************/
+#ifdef L_initgroups
- /* group_list will be NULL if initial malloc failed, which may trigger
- * warnings from various malloc debuggers. */
+#ifdef __USE_BSD
+libc_hidden_proto(setgroups)
+
+int initgroups(const char *user, gid_t gid)
+{
+ int rv;
+ int num_groups = ((unsigned)~0) >> 1; /* INT_MAX */
+ gid_t *group_list = __getgrouplist_internal(user, gid, &num_groups);
+ if (!group_list)
+ return -1;
+ rv = setgroups(num_groups, group_list);
free(group_list);
return rv;
}
diff --git a/libc/stdio/open_memstream.c b/libc/stdio/open_memstream.c
index e7b1cf435..5861017e4 100644
--- a/libc/stdio/open_memstream.c
+++ b/libc/stdio/open_memstream.c
@@ -97,7 +97,7 @@ static int oms_seek(register void *cookie, __offmax_t *pos, int whence)
if (buf) {
*COOKIE->bufloc = COOKIE->buf = buf;
COOKIE->len = leastlen;
- memset(buf + COOKIE->eof, leastlen - COOKIE->eof, 0); /* 0-fill */
+ memset(buf + COOKIE->eof, 0, leastlen - COOKIE->eof); /* 0-fill */
} else {
/* TODO: check glibc errno setting... */
return -1;
@@ -107,7 +107,7 @@ static int oms_seek(register void *cookie, __offmax_t *pos, int whence)
*pos = COOKIE->pos = --leastlen;
if (leastlen > COOKIE->eof) {
- memset(COOKIE->buf + COOKIE->eof, leastlen - COOKIE->eof, 0);
+ memset(COOKIE->buf + COOKIE->eof, 0, leastlen - COOKIE->eof);
*COOKIE->sizeloc = COOKIE->eof;
}
diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c
index 8bc697a48..5cdb6ebf8 100644
--- a/libc/stdio/vsnprintf.c
+++ b/libc/stdio/vsnprintf.c
@@ -46,7 +46,7 @@ int vsnprintf(char *__restrict buf, size_t size,
__INIT_MBSTATE(&(f.__state));
#endif /* __STDIO_MBSTATE */
-#if defined(__USE_OLD_VFPRINTF__) && defined(__UCLIBC_HAS_THREADS__)
+#if (defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__)) && defined(__UCLIBC_HAS_THREADS__)
f.__user_locking = 1; /* Set user locking. */
STDIO_INIT_MUTEX(f.__lock);
#endif