Merge "Change wctype_t from int to long."
diff --git a/libc/Android.mk b/libc/Android.mk
index a2a106a..ed7d055 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -110,6 +110,7 @@
     bionic/clock.cpp \
     bionic/clone.cpp \
     bionic/cmsg_nxthdr.cpp \
+    bionic/connect.cpp \
     bionic/dirent.cpp \
     bionic/dup2.cpp \
     bionic/epoll_create.cpp \
@@ -140,6 +141,8 @@
     bionic/mkdir.cpp \
     bionic/mkfifo.cpp \
     bionic/mknod.cpp \
+    bionic/mntent.cpp \
+    bionic/NetdClientDispatch.cpp \
     bionic/open.cpp \
     bionic/pause.cpp \
     bionic/pipe.cpp \
@@ -256,7 +259,6 @@
 
 libc_upstream_netbsd_src_files := \
     upstream-netbsd/common/lib/libc/hash/sha1/sha1.c \
-    upstream-netbsd/common/lib/libc/inet/inet_addr.c \
     upstream-netbsd/lib/libc/gen/ftw.c \
     upstream-netbsd/lib/libc/gen/nftw.c \
     upstream-netbsd/lib/libc/gen/nice.c \
@@ -265,9 +267,7 @@
     upstream-netbsd/lib/libc/gen/setjmperr.c \
     upstream-netbsd/lib/libc/gen/utime.c \
     upstream-netbsd/lib/libc/gen/utmp.c \
-    upstream-netbsd/lib/libc/inet/inet_ntoa.c \
     upstream-netbsd/lib/libc/inet/inet_ntop.c \
-    upstream-netbsd/lib/libc/inet/inet_pton.c \
     upstream-netbsd/lib/libc/isc/ev_streams.c \
     upstream-netbsd/lib/libc/isc/ev_timers.c \
     upstream-netbsd/lib/libc/regex/regcomp.c \
@@ -356,6 +356,17 @@
     upstream-openbsd/lib/libc/locale/wcsxfrm.c \
     upstream-openbsd/lib/libc/locale/wctob.c \
     upstream-openbsd/lib/libc/locale/wctomb.c \
+    upstream-openbsd/lib/libc/net/htonl.c \
+    upstream-openbsd/lib/libc/net/htons.c \
+    upstream-openbsd/lib/libc/net/inet_addr.c \
+    upstream-openbsd/lib/libc/net/inet_lnaof.c \
+    upstream-openbsd/lib/libc/net/inet_makeaddr.c \
+    upstream-openbsd/lib/libc/net/inet_netof.c \
+    upstream-openbsd/lib/libc/net/inet_network.c \
+    upstream-openbsd/lib/libc/net/inet_ntoa.c \
+    upstream-openbsd/lib/libc/net/inet_pton.c \
+    upstream-openbsd/lib/libc/net/ntohl.c \
+    upstream-openbsd/lib/libc/net/ntohs.c \
     upstream-openbsd/lib/libc/stdio/asprintf.c \
     upstream-openbsd/lib/libc/stdio/clrerr.c \
     upstream-openbsd/lib/libc/stdio/fdopen.c \
@@ -725,7 +736,10 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(libc_bionic_src_files)
-LOCAL_CFLAGS := $(libc_common_cflags) -Werror
+LOCAL_CFLAGS := $(libc_common_cflags) \
+    -Werror \
+    -Wframe-larger-than=2048 \
+
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
@@ -877,6 +891,7 @@
     bionic/debug_stacktrace.cpp \
     bionic/pthread_debug.cpp \
     bionic/libc_init_dynamic.cpp \
+    bionic/NetdClient.cpp \
 
 LOCAL_MODULE := libc
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 93ed85c..e9fb575 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -234,7 +234,7 @@
 int           socket(int, int, int)              arm,arm64,mips,mips64,x86_64
 int           socketpair(int, int, int, int*)    arm,arm64,mips,mips64,x86_64
 int           bind(int, struct sockaddr*, int)  arm,arm64,mips,mips64,x86_64
-int           connect(int, struct sockaddr*, socklen_t)   arm,arm64,mips,mips64,x86_64
+int           __connect:connect(int, struct sockaddr*, socklen_t)   arm,arm64,mips,mips64,x86_64
 int           listen(int, int)                   arm,arm64,mips,mips64,x86_64
 int           accept(int, struct sockaddr*, socklen_t*)  arm,arm64,mips,mips64,x86_64
 int           accept4(int, struct sockaddr*, socklen_t*, int)  arm,arm64,mips,mips64,x86_64
@@ -253,7 +253,7 @@
 # sockets for x86. These are done as an "indexed" call to socketcall syscall.
 int           socket:socketcall:1(int, int, int) x86
 int           bind:socketcall:2(int, struct sockaddr*, int)  x86
-int           connect:socketcall:3(int, struct sockaddr*, socklen_t)   x86
+int           __connect:socketcall:3(int, struct sockaddr*, socklen_t)   x86
 int           listen:socketcall:4(int, int)                   x86
 int           accept:socketcall:5(int, struct sockaddr*, socklen_t*)  x86
 int           getsockname:socketcall:6(int, struct sockaddr*, socklen_t*)  x86
diff --git a/libc/arch-arm/syscalls/connect.S b/libc/arch-arm/syscalls/__connect.S
similarity index 88%
rename from libc/arch-arm/syscalls/connect.S
rename to libc/arch-arm/syscalls/__connect.S
index f7a5188..8cb026c 100644
--- a/libc/arch-arm/syscalls/connect.S
+++ b/libc/arch-arm/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     mov     ip, r7
     ldr     r7, =__NR_connect
     swi     #0
@@ -11,4 +11,4 @@
     bxls    lr
     neg     r0, r0
     b       __set_errno
-END(connect)
+END(__connect)
diff --git a/libc/arch-arm64/syscalls/connect.S b/libc/arch-arm64/syscalls/__connect.S
similarity index 88%
rename from libc/arch-arm64/syscalls/connect.S
rename to libc/arch-arm64/syscalls/__connect.S
index d3cd43d..c46f418 100644
--- a/libc/arch-arm64/syscalls/connect.S
+++ b/libc/arch-arm64/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     stp     x29, x30, [sp, #-16]!
     mov     x29,  sp
     str     x8,       [sp, #-16]!
@@ -18,4 +18,5 @@
     b.hi    __set_errno
 
     ret
-END(connect)
+END(__connect)
+.hidden __connect
diff --git a/libc/arch-mips/syscalls/connect.S b/libc/arch-mips/syscalls/__connect.S
similarity index 89%
rename from libc/arch-mips/syscalls/connect.S
rename to libc/arch-mips/syscalls/__connect.S
index 6f10652..f7ac916 100644
--- a/libc/arch-mips/syscalls/connect.S
+++ b/libc/arch-mips/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     .set noreorder
     .cpload t9
     li v0, __NR_connect
@@ -16,4 +16,4 @@
     j t9
     nop
     .set reorder
-END(connect)
+END(__connect)
diff --git a/libc/arch-mips64/syscalls/connect.S b/libc/arch-mips64/syscalls/__connect.S
similarity index 87%
rename from libc/arch-mips64/syscalls/connect.S
rename to libc/arch-mips64/syscalls/__connect.S
index 8fe2d56..b1475fb 100644
--- a/libc/arch-mips64/syscalls/connect.S
+++ b/libc/arch-mips64/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     .set push
     .set noreorder
     li v0, __NR_connect
@@ -22,4 +22,5 @@
     j t9
     move ra, t0
     .set pop
-END(connect)
+END(__connect)
+.hidden __connect
diff --git a/libc/arch-x86/syscalls/connect.S b/libc/arch-x86/syscalls/__connect.S
similarity index 94%
rename from libc/arch-x86/syscalls/connect.S
rename to libc/arch-x86/syscalls/__connect.S
index c0d73ca..2f53b33 100644
--- a/libc/arch-x86/syscalls/connect.S
+++ b/libc/arch-x86/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     pushl   %ebx
     pushl   %ecx
     .cfi_def_cfa_offset 8
@@ -24,4 +24,4 @@
     popl    %ecx
     popl    %ebx
     ret
-END(connect)
+END(__connect)
diff --git a/libc/arch-x86_64/syscalls/connect.S b/libc/arch-x86_64/syscalls/__connect.S
similarity index 84%
rename from libc/arch-x86_64/syscalls/connect.S
rename to libc/arch-x86_64/syscalls/__connect.S
index 23cdbae..288484e 100644
--- a/libc/arch-x86_64/syscalls/connect.S
+++ b/libc/arch-x86_64/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     movl    $__NR_connect, %eax
     syscall
     cmpq    $-MAX_ERRNO, %rax
@@ -13,4 +13,5 @@
     orq     $-1, %rax
 1:
     ret
-END(connect)
+END(__connect)
+.hidden __connect
diff --git a/libc/bionic/NetdClient.cpp b/libc/bionic/NetdClient.cpp
new file mode 100644
index 0000000..6826ee8
--- /dev/null
+++ b/libc/bionic/NetdClient.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef LIBC_STATIC
+#error NetdClient.cpp should NOT be included in static libc builds.
+#endif
+
+#include <private/NetdClient.h>
+#include <private/libc_logging.h>
+#include <pthread.h>
+
+#include <dlfcn.h>
+
+template <typename FunctionType>
+static void netdClientInitFunction(void* handle, const char* symbol, FunctionType* function) {
+    typedef void (*InitFunctionType)(FunctionType*);
+    InitFunctionType initFunction = reinterpret_cast<InitFunctionType>(dlsym(handle, symbol));
+    if (initFunction != NULL) {
+        initFunction(function);
+    }
+}
+
+static void netdClientInitImpl() {
+    void* netdClientHandle = dlopen("libnetd_client.so", RTLD_LAZY);
+    if (netdClientHandle == NULL) {
+        // If the library is not available, it's not an error. We'll just use
+        // default implementations of functions that it would've overridden.
+        return;
+    }
+    netdClientInitFunction(netdClientHandle, "netdClientInitConnect",
+                           &__netdClientDispatch.connect);
+}
+
+static pthread_once_t netdClientInitOnce = PTHREAD_ONCE_INIT;
+
+extern "C" __LIBC_HIDDEN__ void netdClientInit() {
+    if (pthread_once(&netdClientInitOnce, netdClientInitImpl)) {
+        __libc_format_log(ANDROID_LOG_ERROR, "netdClient",
+                          "Unable to initialize netd_client component.");
+    }
+}
diff --git a/libc/bionic/NetdClientDispatch.cpp b/libc/bionic/NetdClientDispatch.cpp
new file mode 100644
index 0000000..31728d2
--- /dev/null
+++ b/libc/bionic/NetdClientDispatch.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <private/NetdClient.h>
+
+#ifdef __i386__
+#define __socketcall __attribute__((__cdecl__))
+#else
+#define __socketcall
+#endif
+
+extern "C" __socketcall int __connect(int, const sockaddr*, socklen_t);
+
+NetdClientDispatch __netdClientDispatch __attribute__((aligned(32))) = {
+    __connect
+};
diff --git a/libc/bionic/connect.cpp b/libc/bionic/connect.cpp
new file mode 100644
index 0000000..c5db46b
--- /dev/null
+++ b/libc/bionic/connect.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <private/NetdClient.h>
+#include <sys/socket.h>
+
+int connect(int sockfd, const sockaddr* addr, socklen_t addrlen) {
+    return __netdClientDispatch.connect(sockfd, addr, addrlen);
+}
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 61fb887..3d98861 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -58,6 +58,7 @@
   extern void pthread_debug_init(void);
   extern void malloc_debug_init(void);
   extern void malloc_debug_fini(void);
+  extern void netdClientInit(void);
 };
 
 // We flag the __libc_preinit function as a constructor to ensure
@@ -79,6 +80,9 @@
   // Hooks for the debug malloc and pthread libraries to let them know that we're starting up.
   pthread_debug_init();
   malloc_debug_init();
+
+  // Hook for the netd client library to let it know that we're starting up.
+  netdClientInit();
 }
 
 __LIBC_HIDDEN__ void __libc_postfini() {
diff --git a/libc/bionic/mntent.cpp b/libc/bionic/mntent.cpp
new file mode 100644
index 0000000..93b6915
--- /dev/null
+++ b/libc/bionic/mntent.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <mntent.h>
+
+mntent* getmntent(FILE*) {
+  return NULL;
+}
+
+mntent* getmntent_r(FILE*, struct mntent*, char*, int) {
+  return NULL;
+}
+
+FILE* setmntent(const char* path, const char* mode) {
+  return fopen(path, mode);
+}
+
+int endmntent(FILE* fp) {
+  if (fp != NULL) {
+    fclose(fp);
+  }
+  return 1;
+}
diff --git a/libc/bionic/stubs.cpp b/libc/bionic/stubs.cpp
index 41ecd09..9b025df 100644
--- a/libc/bionic/stubs.cpp
+++ b/libc/bionic/stubs.cpp
@@ -444,21 +444,6 @@
   UNIMPLEMENTED;
 }
 
-mntent* getmntent(FILE* /*f*/) {
-  UNIMPLEMENTED;
-  return NULL;
-}
-
-FILE* setmntent(const char*, const char*) {
-  UNIMPLEMENTED;
-  return NULL;
-}
-
-int endmntent(FILE*) {
-  UNIMPLEMENTED;
-  return 1; /* Allways returns 1 according to man */
-}
-
 char* ttyname(int /*fd*/) { // NOLINT: implementing bad function.
   UNIMPLEMENTED;
   return NULL;
diff --git a/libc/bionic/tmpfile.cpp b/libc/bionic/tmpfile.cpp
index 8419ff5..602d407 100644
--- a/libc/bionic/tmpfile.cpp
+++ b/libc/bionic/tmpfile.cpp
@@ -57,22 +57,23 @@
 };
 
 static FILE* __tmpfile_dir(const char* tmp_dir) {
-  char buf[PATH_MAX];
-  int path_length = snprintf(buf, sizeof(buf), "%s/tmp.XXXXXXXXXX", tmp_dir);
-  if (path_length >= static_cast<int>(sizeof(buf))) {
+  char* path = NULL;
+  if (asprintf(&path, "%s/tmp.XXXXXXXXXX", tmp_dir) == -1) {
     return NULL;
   }
 
   int fd;
   {
     ScopedSignalBlocker ssb;
-    fd = mkstemp(buf);
+    fd = mkstemp(path);
     if (fd == -1) {
+      free(path);
       return NULL;
     }
 
     // Unlink the file now so that it's removed when closed.
-    unlink(buf);
+    unlink(path);
+    free(path);
 
     // Can we still use the file now it's unlinked?
     // File systems without hard link support won't have the usual Unix semantics.
diff --git a/libc/include/arpa/inet.h b/libc/include/arpa/inet.h
index b008812..067be1f 100644
--- a/libc/include/arpa/inet.h
+++ b/libc/include/arpa/inet.h
@@ -36,19 +36,18 @@
 
 typedef uint32_t in_addr_t;
 
-extern uint32_t      inet_addr(const char *);
-
-extern int           inet_aton(const char *, struct in_addr *);
-extern char*         inet_ntoa(struct in_addr);
-
-extern int           inet_pton(int, const char *, void *);
-extern const char*   inet_ntop(int, const void *, char *, socklen_t);
-
-extern unsigned int  inet_nsap_addr(const char *, unsigned char *, int);
-extern char*         inet_nsap_ntoa(int, const unsigned char *, char *);
+in_addr_t inet_addr(const char*);
+int inet_aton(const char*, struct in_addr*);
+in_addr_t inet_lnaof(struct in_addr);
+struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
+in_addr_t inet_netof(struct in_addr);
+in_addr_t inet_network(const char*);
+char* inet_ntoa(struct in_addr);
+const char* inet_ntop(int, const void*, char*, socklen_t);
+unsigned int inet_nsap_addr(const char*, unsigned char*, int);
+char* inet_nsap_ntoa(int, const unsigned char*, char*);
+int inet_pton(int, const char*, void*);
 
 __END_DECLS
 
 #endif /* _ARPA_INET_H_ */
-
-
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index bfe4ea4..71eb2e7 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -56,6 +56,8 @@
 struct dirent { __DIRENT64_BODY };
 struct dirent64 { __DIRENT64_BODY };
 
+#undef __DIRENT64_BODY
+
 #define d_fileno d_ino
 
 typedef struct DIR DIR;
diff --git a/libc/include/mntent.h b/libc/include/mntent.h
index 6cc0b18..de285d0 100644
--- a/libc/include/mntent.h
+++ b/libc/include/mntent.h
@@ -35,23 +35,21 @@
 #define MOUNTED _PATH_MOUNTED
 #define MNTTYPE_IGNORE "ignore"
 
-struct mntent
-{
-    char* mnt_fsname;
-    char* mnt_dir;
-    char* mnt_type;
-    char* mnt_opts;
-    int mnt_freq;
-    int mnt_passno;
+struct mntent {
+  char* mnt_fsname;
+  char* mnt_dir;
+  char* mnt_type;
+  char* mnt_opts;
+  int mnt_freq;
+  int mnt_passno;
 };
 
-
 __BEGIN_DECLS
 
-
-struct mntent* getmntent(FILE*);
-FILE* setmntent(const char*, const char*);
 int endmntent(FILE*);
+struct mntent* getmntent(FILE*);
+struct mntent* getmntent_r(FILE*, struct mntent*, char*, int);
+FILE* setmntent(const char*, const char*);
 
 __END_DECLS
 
diff --git a/libc/include/nsswitch.h b/libc/include/nsswitch.h
deleted file mode 100644
index d19d055..0000000
--- a/libc/include/nsswitch.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*	$NetBSD: nsswitch.h,v 1.18 2005/11/29 03:12:58 christos Exp $	*/
-
-/*-
- * Copyright (c) 1997, 1998, 1999, 2004 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Luke Mewburn.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _NSSWITCH_H
-#define _NSSWITCH_H	1
-
-#include <sys/types.h>
-#include <stdarg.h>
-
-#define	NSS_MODULE_INTERFACE_VERSION	0
-
-#ifndef _PATH_NS_CONF
-#define _PATH_NS_CONF	"/etc/nsswitch.conf"
-#endif
-
-#define	NS_CONTINUE	0
-#define	NS_RETURN	1
-
-/*
- * Layout of:
- *	uint32_t ns_src.flags
- */ 
-	/* nsswitch.conf status codes and nsdispatch(3) return values */
-#define	NS_SUCCESS	(1<<0)		/* entry was found */
-#define	NS_UNAVAIL	(1<<1)		/* source not responding, or corrupt */
-#define	NS_NOTFOUND	(1<<2)		/* source responded 'no such entry' */
-#define	NS_TRYAGAIN	(1<<3)		/* source busy, may respond to retrys */
-#define	NS_STATUSMASK	0x000000ff	/* bitmask to get the status flags */
-
-	/* internal nsdispatch(3) flags; not settable in nsswitch.conf(5)  */
-#define	NS_FORCEALL	(1<<8)		/* force all methods to be invoked; */
-
-/*
- * Currently implemented sources.
- */
-#define NSSRC_FILES	"files"		/* local files */
-#define	NSSRC_DNS	"dns"		/* DNS; IN for hosts, HS for others */
-#define	NSSRC_NIS	"nis"		/* YP/NIS */
-#define	NSSRC_COMPAT	"compat"	/* passwd,group in YP compat mode */
-
-/*
- * Currently implemented databases.
- */
-#define NSDB_HOSTS		"hosts"
-#define NSDB_GROUP		"group"
-#define NSDB_GROUP_COMPAT	"group_compat"
-#define NSDB_NETGROUP		"netgroup"
-#define NSDB_NETWORKS		"networks"
-#define NSDB_PASSWD		"passwd"
-#define NSDB_PASSWD_COMPAT	"passwd_compat"
-#define NSDB_SHELLS		"shells"
-
-/*
- * Suggested databases to implement.
- */
-#define NSDB_ALIASES		"aliases"
-#define NSDB_AUTH		"auth"
-#define NSDB_AUTOMOUNT		"automount"
-#define NSDB_BOOTPARAMS		"bootparams"
-#define NSDB_ETHERS		"ethers"
-#define NSDB_EXPORTS		"exports"
-#define NSDB_NETMASKS		"netmasks"
-#define NSDB_PHONES		"phones"
-#define NSDB_PRINTCAP		"printcap"
-#define NSDB_PROTOCOLS		"protocols"
-#define NSDB_REMOTE		"remote"
-#define NSDB_RPC		"rpc"
-#define NSDB_SENDMAILVARS	"sendmailvars"
-#define NSDB_SERVICES		"services"
-#define NSDB_TERMCAP		"termcap"
-#define NSDB_TTYS		"ttys"
-
-/*
- * ns_dtab `callback' function signature.
- */
-typedef	int (*nss_method)(void *, void *, va_list);
-
-/*
- * ns_dtab - `nsswitch dispatch table'
- * Contains an entry for each source and the appropriate function to call.
- */
-typedef struct {
-	const char	 *src;
-	nss_method	 callback;
-	void		 *cb_data;
-} ns_dtab;
-
-/*
- * Macros to help build an ns_dtab[]
- */
-#define NS_FILES_CB(F,C)	{ NSSRC_FILES,	F,	__UNCONST(C) },
-#define NS_COMPAT_CB(F,C)	{ NSSRC_COMPAT,	F,	__UNCONST(C) },
- 
-#ifdef HESIOD
-#   define NS_DNS_CB(F,C)	{ NSSRC_DNS,	F,	__UNCONST(C) },
-#else
-#   define NS_DNS_CB(F,C)
-#endif
-
-#ifdef YP
-#   define NS_NIS_CB(F,C)	{ NSSRC_NIS,	F,	__UNCONST(C) },
-#else
-#   define NS_NIS_CB(F,C)
-#endif
-
-/*
- * ns_src - `nsswitch source'
- * Used by the nsparser routines to store a mapping between a source
- * and its dispatch control flags for a given database.
- */
-typedef struct {
-	const char	*name;
-	uint32_t	 flags;
-} ns_src;
-
-
-/*
- * Default sourcelists (if nsswitch.conf is missing, corrupt,
- * or the requested database doesn't have an entry)
- */
-extern const ns_src __nsdefaultsrc[];
-extern const ns_src __nsdefaultcompat[];
-extern const ns_src __nsdefaultcompat_forceall[];
-extern const ns_src __nsdefaultfiles[];
-extern const ns_src __nsdefaultfiles_forceall[];
-extern const ns_src __nsdefaultnis[];
-extern const ns_src __nsdefaultnis_forceall[];
-
-
-/*
- * ns_mtab - `nsswitch method table'
- * An nsswitch module provides a mapping from (database name, method name)
- * tuples to the nss_method and associated callback data.  Effectively,
- * ns_dtab, but used for dynamically loaded modules.
- */
-typedef struct {
-	const char	*database;
-	const char	*name;
-	nss_method	 method;
-	void		*mdata;
-} ns_mtab;
-
-/*
- * nss_module_register_fn - module registration function
- *	called at module load
- * nss_module_unregister_fn - module un-registration function
- *	called at module unload
- */
-typedef	void (*nss_module_unregister_fn)(ns_mtab *, u_int);
-typedef	ns_mtab *(*nss_module_register_fn)(const char *, u_int *,
-					   nss_module_unregister_fn *);
-
-#ifdef _NS_PRIVATE
-
-/*
- * Private data structures for back-end nsswitch implementation.
- */
-
-/*
- * ns_dbt - `nsswitch database thang'
- * For each database in /etc/nsswitch.conf there is a ns_dbt, with its
- * name and a list of ns_src's containing the source information.
- */
-typedef struct {
-	const char	*name;		/* name of database */
-	ns_src		*srclist;	/* list of sources */
-	u_int		 srclistsize;	/* size of srclist */
-} ns_dbt;
-
-/*
- * ns_mod - `nsswitch module'
- */
-typedef struct {
-	const char	*name;		/* module name */
-	void		*handle;	/* handle from dlopen() */
-	ns_mtab		*mtab;		/* method table */
-	u_int		 mtabsize;	/* size of mtab */
-					/* called to unload module */
-	nss_module_unregister_fn unregister;
-} ns_mod;
-
-#endif /* _NS_PRIVATE */
-
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int	nsdispatch(void *, const ns_dtab [], const char *,
-			const char *, const ns_src [], ...);
-
-#ifdef _NS_PRIVATE
-int		 _nsdbtaddsrc(ns_dbt *, const ns_src *);
-void		 _nsdbtdump(const ns_dbt *);
-int		 _nsdbtput(const ns_dbt *);
-void		 _nsyyerror(const char *);
-int		 _nsyylex(void);
-#endif /* _NS_PRIVATE */
-
-__END_DECLS
-
-#endif /* !_NSSWITCH_H */
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 68115bb..e43b6cc 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -59,10 +59,10 @@
 extern int sched_getcpu(void);
 extern int setns(int, int);
 
-#ifdef __LP32__
-#define CPU_SETSIZE 32
-#else
+#ifdef __LP64__
 #define CPU_SETSIZE 1024
+#else
+#define CPU_SETSIZE 32
 #endif
 
 #define __CPU_BITTYPE  unsigned long int  /* mandated by the kernel  */
diff --git a/libc/include/sys/endian.h b/libc/include/sys/endian.h
index cbde121..be4c905 100644
--- a/libc/include/sys/endian.h
+++ b/libc/include/sys/endian.h
@@ -39,6 +39,8 @@
 #include <sys/cdefs.h>
 #include <machine/endian.h>
 
+#include <stdint.h>
+
 #define _LITTLE_ENDIAN	1234
 #define _BIG_ENDIAN	4321
 #define _PDP_ENDIAN	3412
@@ -186,14 +188,22 @@
 #define letoh64(x) (x)
 #endif /* __BSD_VISIBLE */
 
-#define htons(x) __swap16(x)
+/* glibc compatibility. */
+__BEGIN_DECLS
+uint32_t htonl(uint32_t) __pure2;
+uint16_t htons(uint16_t) __pure2;
+uint32_t ntohl(uint32_t) __pure2;
+uint16_t ntohs(uint16_t) __pure2;
+__END_DECLS
+
 #define htonl(x) __swap32(x)
-#define ntohs(x) __swap16(x)
+#define htons(x) __swap16(x)
 #define ntohl(x) __swap32(x)
+#define ntohs(x) __swap16(x)
 
 /* Bionic additions */
-#define ntohq(x) __swap64(x)
 #define htonq(x) __swap64(x)
+#define ntohq(x) __swap64(x)
 
 #define __LITTLE_ENDIAN_BITFIELD
 
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index e62e76d..c0c168b 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -130,6 +130,8 @@
 struct stat { __STAT64_BODY };
 struct stat64 { __STAT64_BODY };
 
+#undef __STAT64_BODY
+
 #define st_atimensec st_atime_nsec
 #define st_mtimensec st_mtime_nsec
 #define st_ctimensec st_ctime_nsec
diff --git a/libc/include/sys/vfs.h b/libc/include/sys/vfs.h
index cd6044d..5358ffb 100644
--- a/libc/include/sys/vfs.h
+++ b/libc/include/sys/vfs.h
@@ -107,6 +107,8 @@
 struct statfs { __STATFS64_BODY };
 struct statfs64 { __STATFS64_BODY };
 
+#undef __STATFS64_BODY
+
 /* Declare that we have the f_namelen, f_frsize, and f_flags fields. */
 #define _STATFS_F_NAMELEN
 #define _STATFS_F_FRSIZE
diff --git a/libc/private/NetdClient.h b/libc/private/NetdClient.h
new file mode 100644
index 0000000..48c05cb
--- /dev/null
+++ b/libc/private/NetdClient.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PRIVATE_NETD_CLIENT_H
+#define PRIVATE_NETD_CLIENT_H
+
+#include <sys/socket.h>
+
+struct NetdClientDispatch {
+    int (*connect)(int, const sockaddr*, socklen_t);
+};
+
+extern NetdClientDispatch __netdClientDispatch;
+
+#endif  // PRIVATE_NETD_CLIENT_H
diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_ntop.c b/libc/upstream-netbsd/lib/libc/inet/inet_ntop.c
index 00c55a8..d27a5b1 100644
--- a/libc/upstream-netbsd/lib/libc/inet/inet_ntop.c
+++ b/libc/upstream-netbsd/lib/libc/inet/inet_ntop.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: inet_ntop.c,v 1.9 2012/03/20 17:08:13 matt Exp $	*/
+/*	$NetBSD: inet_ntop.c,v 1.11 2014/02/10 16:30:54 christos Exp $	*/
 
 /*
  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
@@ -22,7 +22,7 @@
 #if 0
 static const char rcsid[] = "Id: inet_ntop.c,v 1.5 2005/11/03 22:59:52 marka Exp";
 #else
-__RCSID("$NetBSD: inet_ntop.c,v 1.9 2012/03/20 17:08:13 matt Exp $");
+__RCSID("$NetBSD: inet_ntop.c,v 1.11 2014/02/10 16:30:54 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -74,12 +74,12 @@
 
 	switch (af) {
 	case AF_INET:
-		return (inet_ntop4(src, dst, size));
+		return inet_ntop4(src, dst, size);
 	case AF_INET6:
-		return (inet_ntop6(src, dst, size));
+		return inet_ntop6(src, dst, size);
 	default:
 		errno = EAFNOSUPPORT;
-		return (NULL);
+		return NULL;
 	}
 	/* NOTREACHED */
 }
@@ -106,12 +106,10 @@
 
 	l = snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u",
 	    src[0], src[1], src[2], src[3]);
-	if (l <= 0 || (socklen_t) l >= size) {
-		errno = ENOSPC;
-		return (NULL);
-	}
+	if (l <= 0 || (socklen_t) l >= size)
+		return NULL;
 	strlcpy(dst, tmp, size);
-	return (dst);
+	return dst;
 }
 
 /* const char *
@@ -189,7 +187,7 @@
 		/* Are we following an initial run of 0x00s or any real hex? */
 		if (i != 0) {
 			if (tp + 1 >= ep)
-				return (NULL);
+				goto out;
 			*tp++ = ':';
 		}
 		/* Is this address an encapsulated IPv4? */
@@ -197,36 +195,37 @@
 		    (best.len == 6 ||
 		    (best.len == 7 && words[7] != 0x0001) ||
 		    (best.len == 5 && words[5] == 0xffff))) {
-			if (!inet_ntop4(src+12, tp, (socklen_t)(ep - tp)))
-				return (NULL);
+			if (!inet_ntop4(src + 12, tp, (socklen_t)(ep - tp)))
+				goto out;
 			tp += strlen(tp);
 			break;
 		}
 		advance = snprintf(tp, (size_t)(ep - tp), "%x", words[i]);
 		if (advance <= 0 || advance >= ep - tp)
-			return (NULL);
+			goto out;
 		tp += advance;
 	}
 	/* Was it a trailing run of 0x00's? */
 	if (best.base != -1 && (best.base + best.len) == 
 	    (NS_IN6ADDRSZ / NS_INT16SZ)) {
 		if (tp + 1 >= ep)
-			return (NULL);
+			goto out;
 		*tp++ = ':';
 	}
 	if (tp + 1 >= ep)
-		return (NULL);
+		goto out;
 	*tp++ = '\0';
 
 	/*
 	 * Check for overflow, copy, and we're done.
 	 */
-	if ((size_t)(tp - tmp) > size) {
-		errno = ENOSPC;
-		return (NULL);
-	}
+	if ((size_t)(tp - tmp) > size)
+		goto out;
 	strlcpy(dst, tmp, size);
-	return (dst);
+	return dst;
+out:
+	errno = ENOSPC;
+	return NULL;
 }
 
 /*! \file */
diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_pton.c b/libc/upstream-netbsd/lib/libc/inet/inet_pton.c
deleted file mode 100644
index c1e9a69..0000000
--- a/libc/upstream-netbsd/lib/libc/inet/inet_pton.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*	$NetBSD: inet_pton.c,v 1.8 2012/03/13 21:13:38 christos Exp $	*/
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996,1999 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static const char rcsid[] = "Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Exp";
-#else
-__RCSID("$NetBSD: inet_pton.c,v 1.8 2012/03/13 21:13:38 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include "port_before.h"
-
-#include "namespace.h"
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <stddef.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include "port_after.h"
-
-#ifdef __weak_alias
-__weak_alias(inet_pton,_inet_pton)
-#endif
-
-/*%
- * WARNING: Don't even consider trying to compile this on a system where
- * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
- */
-
-static int	inet_pton4(const char *src, u_char *dst, int pton);
-static int	inet_pton6(const char *src, u_char *dst);
-
-/* int
- * inet_pton(af, src, dst)
- *	convert from presentation format (which usually means ASCII printable)
- *	to network format (which is usually some kind of binary format).
- * return:
- *	1 if the address was valid for the specified address family
- *	0 if the address wasn't valid (`dst' is untouched in this case)
- *	-1 if some other error occurred (`dst' is untouched in this case, too)
- * author:
- *	Paul Vixie, 1996.
- */
-int
-inet_pton(int af, const char *src, void *dst)
-{
-
-	_DIAGASSERT(src != NULL);
-	_DIAGASSERT(dst != NULL);
-
-	switch (af) {
-	case AF_INET:
-		return (inet_pton4(src, dst, 1));
-	case AF_INET6:
-		return (inet_pton6(src, dst));
-	default:
-		errno = EAFNOSUPPORT;
-		return (-1);
-	}
-	/* NOTREACHED */
-}
-
-/* int
- * inet_pton4(src, dst, pton)
- *	when last arg is 0: inet_aton(). with hexadecimal, octal and shorthand.
- *	when last arg is 1: inet_pton(). decimal dotted-quad only.
- * return:
- *	1 if `src' is a valid input, else 0.
- * notice:
- *	does not touch `dst' unless it's returning 1.
- * author:
- *	Paul Vixie, 1996.
- */
-static int
-inet_pton4(const char *src, u_char *dst, int pton)
-{
-	u_int32_t val;
-	u_int digit, base;
-	ptrdiff_t n;
-	unsigned char c;
-	u_int parts[4];
-	u_int *pp = parts;
-
-	_DIAGASSERT(src != NULL);
-	_DIAGASSERT(dst != NULL);
-
-	c = *src;
-	for (;;) {
-		/*
-		 * Collect number up to ``.''.
-		 * Values are specified as for C:
-		 * 0x=hex, 0=octal, isdigit=decimal.
-		 */
-		if (!isdigit(c))
-			return (0);
-		val = 0; base = 10;
-		if (c == '0') {
-			c = *++src;
-			if (c == 'x' || c == 'X')
-				base = 16, c = *++src;
-			else if (isdigit(c) && c != '9')
-				base = 8;
-		}
-		/* inet_pton() takes decimal only */
-		if (pton && base != 10)
-			return (0);
-		for (;;) {
-			if (isdigit(c)) {
-				digit = c - '0';
-				if (digit >= base)
-					break;
-				val = (val * base) + digit;
-				c = *++src;
-			} else if (base == 16 && isxdigit(c)) {
-				digit = c + 10 - (islower(c) ? 'a' : 'A');
-				if (digit >= 16)
-					break;
-				val = (val << 4) | digit;
-				c = *++src;
-			} else
-				break;
-		}
-		if (c == '.') {
-			/*
-			 * Internet format:
-			 *	a.b.c.d
-			 *	a.b.c	(with c treated as 16 bits)
-			 *	a.b	(with b treated as 24 bits)
-			 *	a	(with a treated as 32 bits)
-			 */
-			if (pp >= parts + 3)
-				return (0);
-			*pp++ = val;
-			c = *++src;
-		} else
-			break;
-	}
-	/*
-	 * Check for trailing characters.
-	 */
-	if (c != '\0' && !isspace(c))
-		return (0);
-	/*
-	 * Concoct the address according to
-	 * the number of parts specified.
-	 */
-	n = pp - parts + 1;
-	/* inet_pton() takes dotted-quad only.  it does not take shorthand. */
-	if (pton && n != 4)
-		return (0);
-	switch (n) {
-
-	case 0:
-		return (0);		/* initial nondigit */
-
-	case 1:				/* a -- 32 bits */
-		break;
-
-	case 2:				/* a.b -- 8.24 bits */
-		if (parts[0] > 0xff || val > 0xffffff)
-			return (0);
-		val |= parts[0] << 24;
-		break;
-
-	case 3:				/* a.b.c -- 8.8.16 bits */
-		if ((parts[0] | parts[1]) > 0xff || val > 0xffff)
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16);
-		break;
-
-	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
-		if ((parts[0] | parts[1] | parts[2] | val) > 0xff)
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-		break;
-	}
-	if (dst) {
-		val = htonl(val);
-		memcpy(dst, &val, NS_INADDRSZ);
-	}
-	return (1);
-}
-
-/* int
- * inet_pton6(src, dst)
- *	convert presentation level address to network order binary form.
- * return:
- *	1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- *	(1) does not touch `dst' unless it's returning 1.
- *	(2) :: in a full address is silently ignored.
- * credit:
- *	inspired by Mark Andrews.
- * author:
- *	Paul Vixie, 1996.
- */
-static int
-inet_pton6(const char *src, u_char *dst)
-{
-	static const char xdigits_l[] = "0123456789abcdef",
-			  xdigits_u[] = "0123456789ABCDEF";
-	u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
-	const char *xdigits, *curtok;
-	int ch, seen_xdigits;
-	u_int val;
-
-	_DIAGASSERT(src != NULL);
-	_DIAGASSERT(dst != NULL);
-
-	memset((tp = tmp), '\0', NS_IN6ADDRSZ);
-	endp = tp + NS_IN6ADDRSZ;
-	colonp = NULL;
-	/* Leading :: requires some special handling. */
-	if (*src == ':')
-		if (*++src != ':')
-			return (0);
-	curtok = src;
-	seen_xdigits = 0;
-	val = 0;
-	while ((ch = *src++) != '\0') {
-		const char *pch;
-
-		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
-			pch = strchr((xdigits = xdigits_u), ch);
-		if (pch != NULL) {
-			val <<= 4;
-			val |= (int)(pch - xdigits);
-			if (++seen_xdigits > 4)
-				return (0);
-			continue;
-		}
-		if (ch == ':') {
-			curtok = src;
-			if (!seen_xdigits) {
-				if (colonp)
-					return (0);
-				colonp = tp;
-				continue;
-			} else if (*src == '\0')
-				return (0);
-			if (tp + NS_INT16SZ > endp)
-				return (0);
-			*tp++ = (u_char) (val >> 8) & 0xff;
-			*tp++ = (u_char) val & 0xff;
-			seen_xdigits = 0;
-			val = 0;
-			continue;
-		}
-		if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
-		    inet_pton4(curtok, tp, 1) > 0) {
-			tp += NS_INADDRSZ;
-			seen_xdigits = 0;
-			break;	/*%< '\\0' was seen by inet_pton4(). */
-		}
-		return (0);
-	}
-	if (seen_xdigits) {
-		if (tp + NS_INT16SZ > endp)
-			return (0);
-		*tp++ = (u_char) (val >> 8) & 0xff;
-		*tp++ = (u_char) val & 0xff;
-	}
-	if (colonp != NULL) {
-		/*
-		 * Since some memmove()'s erroneously fail to handle
-		 * overlapping regions, we'll do the shift by hand.
-		 */
-		const ptrdiff_t n = tp - colonp;
-		int i;
-
-		if (tp == endp)
-			return (0);
-		for (i = 1; i <= n; i++) {
-			endp[- i] = colonp[n - i];
-			colonp[n - i] = 0;
-		}
-		tp = endp;
-	}
-	if (tp != endp)
-		return (0);
-	memcpy(dst, tmp, NS_IN6ADDRSZ);
-	return (1);
-}
-
-/*! \file */
diff --git a/libc/upstream-openbsd/lib/libc/net/htonl.c b/libc/upstream-openbsd/lib/libc/net/htonl.c
new file mode 100644
index 0000000..5ab4189
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/net/htonl.c
@@ -0,0 +1,21 @@
+/*	$OpenBSD: htonl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/types.h>
+#include <machine/endian.h>
+
+#undef htonl
+
+u_int32_t
+htonl(u_int32_t x)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+	u_char *s = (u_char *)&x;
+	return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
+#else
+	return x;
+#endif
+}
diff --git a/libc/upstream-openbsd/lib/libc/net/htons.c b/libc/upstream-openbsd/lib/libc/net/htons.c
new file mode 100644
index 0000000..c8b73fd
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/net/htons.c
@@ -0,0 +1,21 @@
+/*	$OpenBSD: htons.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/types.h>
+#include <machine/endian.h>
+
+#undef htons
+
+u_int16_t
+htons(u_int16_t x)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+	u_char *s = (u_char *) &x;
+	return (u_int16_t)(s[0] << 8 | s[1]);
+#else
+	return x;
+#endif
+}
diff --git a/libc/upstream-netbsd/common/lib/libc/inet/inet_addr.c b/libc/upstream-openbsd/lib/libc/net/inet_addr.c
similarity index 62%
rename from libc/upstream-netbsd/common/lib/libc/inet/inet_addr.c
rename to libc/upstream-openbsd/lib/libc/net/inet_addr.c
index 1360ce9..18762ab 100644
--- a/libc/upstream-netbsd/common/lib/libc/inet/inet_addr.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_addr.c
@@ -1,6 +1,8 @@
-/*	$NetBSD: inet_addr.c,v 1.3 2012/03/09 15:41:16 christos Exp $	*/
+/*	$OpenBSD: inet_addr.c,v 1.10 2013/11/24 23:51:28 deraadt Exp $	*/
 
 /*
+ * ++Copyright++ 1983, 1990, 1993
+ * -
  * Copyright (c) 1983, 1990, 1993
  *    The Regents of the University of California.  All rights reserved.
  * 
@@ -12,11 +14,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- * 	This product includes software developed by the University of
- * 	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * 
@@ -31,9 +29,7 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- */
-
-/*
+ * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  * 
  * Permission to use, copy, modify, and distribute this software for any
@@ -51,63 +47,23 @@
  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  * SOFTWARE.
+ * -
+ * --Copyright--
  */
 
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#if !defined(_KERNEL) && !defined(_STANDALONE)
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static const char sccsid[] = "@(#)inet_addr.c	8.1 (Berkeley) 6/17/93";
-static const char rcsid[] = "Id: inet_addr.c,v 1.2.206.2 2004/03/17 00:29:45 marka Exp";
-#else
-__RCSID("$NetBSD: inet_addr.c,v 1.3 2012/03/09 15:41:16 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include "port_before.h"
-
-#include "namespace.h"
 #include <sys/types.h>
 #include <sys/param.h>
-
 #include <netinet/in.h>
 #include <arpa/inet.h>
-
 #include <ctype.h>
 
-#include "port_after.h"
-
-#ifdef __weak_alias
-__weak_alias(inet_aton,_inet_aton)
-#endif
-#else
-#include <lib/libkern/libkern.h>
-#include <netinet/in.h>
-#endif
-
 /*
  * Ascii internet address interpretation routine.
  * The value returned is in network order.
  */
-uint32_t
-inet_addr(const char *cp) {
+in_addr_t
+inet_addr(const char *cp)
+{
 	struct in_addr val;
 
 	if (inet_aton(cp, &val))
@@ -123,14 +79,13 @@
  * cannot distinguish between failure and a local broadcast address.
  */
 int
-inet_aton(const char *cp, struct in_addr *addr) {
-	uint32_t val;
-	int base;
-	size_t n;
+inet_aton(const char *cp, struct in_addr *addr)
+{
+	in_addr_t val;
+	int base, n;
 	char c;
-	uint8_t parts[4];
-	uint8_t *pp = parts;
-	int digit;
+	u_int parts[4];
+	u_int *pp = parts;
 
 	c = *cp;
 	for (;;) {
@@ -141,29 +96,25 @@
 		 */
 		if (!isdigit((unsigned char)c))
 			return (0);
-		val = 0; base = 10; digit = 0;
+		val = 0; base = 10;
 		if (c == '0') {
 			c = *++cp;
 			if (c == 'x' || c == 'X')
 				base = 16, c = *++cp;
-			else {
+			else
 				base = 8;
-				digit = 1 ;
-			}
 		}
 		for (;;) {
-			if (isascii(c) && isdigit((unsigned char)c)) {
-				if (base == 8 && (c == '8' || c == '9'))
-					return (0);
+			if (isascii((unsigned char)c) &&
+			    isdigit((unsigned char)c)) {
 				val = (val * base) + (c - '0');
 				c = *++cp;
-				digit = 1;
-			} else if (base == 16 && isascii(c) && 
-				   isxdigit((unsigned char)c)) {
+			} else if (base == 16 &&
+			    isascii((unsigned char)c) &&
+			    isxdigit((unsigned char)c)) {
 				val = (val << 4) |
-					(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
+				    (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
 				c = *++cp;
-				digit = 1;
 			} else
 				break;
 		}
@@ -174,7 +125,7 @@
 			 *	a.b.c	(with c treated as 16 bits)
 			 *	a.b	(with b treated as 24 bits)
 			 */
-			if (pp >= parts + 3 || val > 0xffU)
+			if (pp >= parts + 3)
 				return (0);
 			*pp++ = val;
 			c = *++cp;
@@ -184,12 +135,8 @@
 	/*
 	 * Check for trailing characters.
 	 */
-	if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c)))
-		return (0);
-	/*
-	 * Did we get a valid digit?
-	 */
-	if (!digit)
+	if (c != '\0' &&
+	    (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
 		return (0);
 	/*
 	 * Concoct the address according to
@@ -197,28 +144,32 @@
 	 */
 	n = pp - parts + 1;
 	switch (n) {
+
+	case 0:
+		return (0);		/* initial nondigit */
+
 	case 1:				/* a -- 32 bits */
 		break;
 
 	case 2:				/* a.b -- 8.24 bits */
-		if (val > 0xffffffU)
+		if ((val > 0xffffff) || (parts[0] > 0xff))
 			return (0);
 		val |= parts[0] << 24;
 		break;
 
 	case 3:				/* a.b.c -- 8.8.16 bits */
-		if (val > 0xffffU)
+		if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
 			return (0);
 		val |= (parts[0] << 24) | (parts[1] << 16);
 		break;
 
 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
-		if (val > 0xffU)
+		if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
 			return (0);
 		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
 		break;
 	}
-	if (addr != NULL)
+	if (addr)
 		addr->s_addr = htonl(val);
 	return (1);
 }
diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c b/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c
similarity index 67%
copy from libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
copy to libc/upstream-openbsd/lib/libc/net/inet_lnaof.c
index 6ed023b..b1a58cd 100644
--- a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c
@@ -1,5 +1,4 @@
-/*	$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $	*/
-
+/*	$OpenBSD: inet_lnaof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -29,36 +28,24 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)inet_ntoa.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include "namespace.h"
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __weak_alias
-__weak_alias(inet_ntoa,_inet_ntoa)
-#endif
 
 /*
- * Convert network-format internet address
- * to base 256 d.d.d.d representation.
+ * Return the local network address portion of an
+ * internet address; handles class a/b/c network
+ * number formats.
  */
-/*const*/ char *
-inet_ntoa(struct in_addr in) {
-	static char ret[18];
+in_addr_t
+inet_lnaof(struct in_addr in)
+{
+	in_addr_t i = ntohl(in.s_addr);
 
-	strlcpy(ret, "[inet_ntoa error]", sizeof(ret));
-	(void) inet_ntop(AF_INET, &in, ret, (socklen_t)sizeof ret);
-	return ret;
+	if (IN_CLASSA(i))
+		return ((i)&IN_CLASSA_HOST);
+	else if (IN_CLASSB(i))
+		return ((i)&IN_CLASSB_HOST);
+	else
+		return ((i)&IN_CLASSC_HOST);
 }
diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c b/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c
similarity index 67%
copy from libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
copy to libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c
index 6ed023b..87d9325 100644
--- a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c
@@ -1,5 +1,4 @@
-/*	$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $	*/
-
+/*	$OpenBSD: inet_makeaddr.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -29,36 +28,27 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)inet_ntoa.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include "namespace.h"
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __weak_alias
-__weak_alias(inet_ntoa,_inet_ntoa)
-#endif
 
 /*
- * Convert network-format internet address
- * to base 256 d.d.d.d representation.
+ * Formulate an Internet address from network + host.  Used in
+ * building addresses stored in the ifnet structure.
  */
-/*const*/ char *
-inet_ntoa(struct in_addr in) {
-	static char ret[18];
+struct in_addr
+inet_makeaddr(in_addr_t net, in_addr_t host)
+{
+	in_addr_t addr;
 
-	strlcpy(ret, "[inet_ntoa error]", sizeof(ret));
-	(void) inet_ntop(AF_INET, &in, ret, (socklen_t)sizeof ret);
-	return ret;
+	if (net < 128)
+		addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
+	else if (net < 65536)
+		addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
+	else if (net < 16777216L)
+		addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
+	else
+		addr = net | host;
+	addr = htonl(addr);
+	return (*(struct in_addr *)&addr);
 }
diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c b/libc/upstream-openbsd/lib/libc/net/inet_netof.c
similarity index 67%
copy from libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
copy to libc/upstream-openbsd/lib/libc/net/inet_netof.c
index 6ed023b..2f468c3 100644
--- a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_netof.c
@@ -1,5 +1,4 @@
-/*	$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $	*/
-
+/*	$OpenBSD: inet_netof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -29,36 +28,23 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)inet_ntoa.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include "namespace.h"
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __weak_alias
-__weak_alias(inet_ntoa,_inet_ntoa)
-#endif
 
 /*
- * Convert network-format internet address
- * to base 256 d.d.d.d representation.
+ * Return the network number from an internet
+ * address; handles class a/b/c network #'s.
  */
-/*const*/ char *
-inet_ntoa(struct in_addr in) {
-	static char ret[18];
+in_addr_t
+inet_netof(struct in_addr in)
+{
+	in_addr_t i = ntohl(in.s_addr);
 
-	strlcpy(ret, "[inet_ntoa error]", sizeof(ret));
-	(void) inet_ntop(AF_INET, &in, ret, (socklen_t)sizeof ret);
-	return ret;
+	if (IN_CLASSA(i))
+		return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
+	else if (IN_CLASSB(i))
+		return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
+	else
+		return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
 }
diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c b/libc/upstream-openbsd/lib/libc/net/inet_network.c
similarity index 62%
copy from libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
copy to libc/upstream-openbsd/lib/libc/net/inet_network.c
index 6ed023b..ecf554e 100644
--- a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_network.c
@@ -1,5 +1,4 @@
-/*	$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $	*/
-
+/*	$OpenBSD: inet_network.c,v 1.11 2013/11/25 17:29:19 deraadt Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -29,36 +28,57 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)inet_ntoa.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include "namespace.h"
 #include <sys/types.h>
-#include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __weak_alias
-__weak_alias(inet_ntoa,_inet_ntoa)
-#endif
+#include <ctype.h>
 
 /*
- * Convert network-format internet address
- * to base 256 d.d.d.d representation.
+ * Internet network address interpretation routine.
+ * The library routines call this routine to interpret
+ * network numbers.
  */
-/*const*/ char *
-inet_ntoa(struct in_addr in) {
-	static char ret[18];
+in_addr_t
+inet_network(const char *cp)
+{
+	in_addr_t val, base, n;
+	u_char c;
+	in_addr_t parts[4], *pp = parts;
+	int i;
 
-	strlcpy(ret, "[inet_ntoa error]", sizeof(ret));
-	(void) inet_ntop(AF_INET, &in, ret, (socklen_t)sizeof ret);
-	return ret;
+again:
+	val = 0; base = 10;
+	if (*cp == '0')
+		base = 8, cp++;
+	if (*cp == 'x' || *cp == 'X')
+		base = 16, cp++;
+	while ((c = *cp)) {
+		if (isdigit(c)) {
+			val = (val * base) + (c - '0');
+			cp++;
+			continue;
+		}
+		if (base == 16 && isxdigit(c)) {
+			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
+			cp++;
+			continue;
+		}
+		break;
+	}
+	if (*cp == '.') {
+		if (pp >= parts + 3)
+			return (INADDR_NONE);
+		*pp++ = val, cp++;
+		goto again;
+	}
+	if (*cp && !isspace(*cp))
+		return (INADDR_NONE);
+	*pp++ = val;
+	n = pp - parts;
+	for (val = 0, i = 0; i < 4; i++) {
+		val <<= 8;
+		if (i < n)
+			val |= parts[i] & 0xff;
+	}
+	return (val);
 }
diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c b/libc/upstream-openbsd/lib/libc/net/inet_ntoa.c
similarity index 73%
rename from libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
rename to libc/upstream-openbsd/lib/libc/net/inet_ntoa.c
index 6ed023b..ff5d93d 100644
--- a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_ntoa.c
@@ -1,5 +1,4 @@
-/*	$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $	*/
-
+/*	$OpenBSD: inet_ntoa.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -29,36 +28,24 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)inet_ntoa.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include "namespace.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __weak_alias
-__weak_alias(inet_ntoa,_inet_ntoa)
-#endif
-
 /*
  * Convert network-format internet address
  * to base 256 d.d.d.d representation.
  */
-/*const*/ char *
-inet_ntoa(struct in_addr in) {
-	static char ret[18];
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
 
-	strlcpy(ret, "[inet_ntoa error]", sizeof(ret));
-	(void) inet_ntop(AF_INET, &in, ret, (socklen_t)sizeof ret);
-	return ret;
+char *
+inet_ntoa(struct in_addr in)
+{
+	static char b[18];
+	char *p;
+
+	p = (char *)&in;
+#define	UC(b)	(((int)b)&0xff)
+	(void)snprintf(b, sizeof(b),
+	    "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
+	return (b);
 }
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_ntop.c b/libc/upstream-openbsd/lib/libc/net/inet_ntop.c
new file mode 100644
index 0000000..359acd8
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/net/inet_ntop.c
@@ -0,0 +1,205 @@
+/*	$OpenBSD: inet_ntop.c,v 1.9 2014/02/05 14:20:43 millert Exp $	*/
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
+static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
+
+/* const char *
+ * inet_ntop(af, src, dst, size)
+ *	convert a network format address to presentation format.
+ * return:
+ *	pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ *	Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(int af, const void *src, char *dst, socklen_t size)
+{
+	switch (af) {
+	case AF_INET:
+		return (inet_ntop4(src, dst, (size_t)size));
+	case AF_INET6:
+		return (inet_ntop6(src, dst, (size_t)size));
+	default:
+		errno = EAFNOSUPPORT;
+		return (NULL);
+	}
+	/* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ *	format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ *	`dst' (as a const)
+ * notes:
+ *	(1) uses no statics
+ *	(2) takes a u_char* not an in_addr as input
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const u_char *src, char *dst, size_t size)
+{
+	static const char fmt[] = "%u.%u.%u.%u";
+	char tmp[sizeof "255.255.255.255"];
+	int l;
+
+	l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]);
+	if (l <= 0 || l >= size) {
+		errno = ENOSPC;
+		return (NULL);
+	}
+	strlcpy(dst, tmp, size);
+	return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ *	convert IPv6 binary address into presentation (printable) format
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(const u_char *src, char *dst, size_t size)
+{
+	/*
+	 * Note that int32_t and int16_t need only be "at least" large enough
+	 * to contain a value of the specified size.  On some systems, like
+	 * Crays, there is no such thing as an integer variable with 16 bits.
+	 * Keep this in mind if you think this function should have been coded
+	 * to use pointer overlays.  All the world's not a VAX.
+	 */
+	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+	char *tp, *ep;
+	struct { int base, len; } best, cur;
+	u_int words[IN6ADDRSZ / INT16SZ];
+	int i;
+	int advance;
+
+	/*
+	 * Preprocess:
+	 *	Copy the input (bytewise) array into a wordwise array.
+	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
+	 */
+	memset(words, '\0', sizeof words);
+	for (i = 0; i < IN6ADDRSZ; i++)
+		words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+	best.base = -1;
+	cur.base = -1;
+	for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+		if (words[i] == 0) {
+			if (cur.base == -1)
+				cur.base = i, cur.len = 1;
+			else
+				cur.len++;
+		} else {
+			if (cur.base != -1) {
+				if (best.base == -1 || cur.len > best.len)
+					best = cur;
+				cur.base = -1;
+			}
+		}
+	}
+	if (cur.base != -1) {
+		if (best.base == -1 || cur.len > best.len)
+			best = cur;
+	}
+	if (best.base != -1 && best.len < 2)
+		best.base = -1;
+
+	/*
+	 * Format the result.
+	 */
+	tp = tmp;
+	ep = tmp + sizeof(tmp);
+	for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) {
+		/* Are we inside the best run of 0x00's? */
+		if (best.base != -1 && i >= best.base &&
+		    i < (best.base + best.len)) {
+			if (i == best.base) {
+				if (tp + 1 >= ep) {
+					errno = ENOSPC;
+					return (NULL);
+				}
+				*tp++ = ':';
+			}
+			continue;
+		}
+		/* Are we following an initial run of 0x00s or any real hex? */
+		if (i != 0) {
+			if (tp + 1 >= ep) {
+				errno = ENOSPC;
+				return (NULL);
+			}
+			*tp++ = ':';
+		}
+		/* Is this address an encapsulated IPv4? */
+		if (i == 6 && best.base == 0 &&
+		    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+			if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
+				return (NULL);
+			tp += strlen(tp);
+			break;
+		}
+		advance = snprintf(tp, ep - tp, "%x", words[i]);
+		if (advance <= 0 || advance >= ep - tp) {
+			errno = ENOSPC;
+			return (NULL);
+		}
+		tp += advance;
+	}
+	/* Was it a trailing run of 0x00's? */
+	if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
+		if (tp + 1 >= ep) {
+			errno = ENOSPC;
+			return (NULL);
+		}
+		*tp++ = ':';
+	}
+	if (tp + 1 >= ep) {
+		errno = ENOSPC;
+		return (NULL);
+	}
+	*tp++ = '\0';
+
+	/*
+	 * Check for overflow, copy, and we're done.
+	 */
+	if ((size_t)(tp - tmp) > size) {
+		errno = ENOSPC;
+		return (NULL);
+	}
+	strlcpy(dst, tmp, size);
+	return (dst);
+}
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_pton.c b/libc/upstream-openbsd/lib/libc/net/inet_pton.c
new file mode 100644
index 0000000..7e521c3
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/net/inet_pton.c
@@ -0,0 +1,213 @@
+/*	$OpenBSD: inet_pton.c,v 1.8 2010/05/06 15:47:14 claudio Exp $	*/
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int	inet_pton4(const char *src, u_char *dst);
+static int	inet_pton6(const char *src, u_char *dst);
+
+/* int
+ * inet_pton(af, src, dst)
+ *	convert from presentation format (which usually means ASCII printable)
+ *	to network format (which is usually some kind of binary format).
+ * return:
+ *	1 if the address was valid for the specified address family
+ *	0 if the address wasn't valid (`dst' is untouched in this case)
+ *	-1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *	Paul Vixie, 1996.
+ */
+int
+inet_pton(int af, const char *src, void *dst)
+{
+	switch (af) {
+	case AF_INET:
+		return (inet_pton4(src, dst));
+	case AF_INET6:
+		return (inet_pton6(src, dst));
+	default:
+		errno = EAFNOSUPPORT;
+		return (-1);
+	}
+	/* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *	like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *	1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *	does not touch `dst' unless it's returning 1.
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, u_char *dst)
+{
+	static const char digits[] = "0123456789";
+	int saw_digit, octets, ch;
+	u_char tmp[INADDRSZ], *tp;
+
+	saw_digit = 0;
+	octets = 0;
+	*(tp = tmp) = 0;
+	while ((ch = *src++) != '\0') {
+		const char *pch;
+
+		if ((pch = strchr(digits, ch)) != NULL) {
+			u_int new = *tp * 10 + (pch - digits);
+
+			if (new > 255)
+				return (0);
+			if (! saw_digit) {
+				if (++octets > 4)
+					return (0);
+				saw_digit = 1;
+			}
+			*tp = new;
+		} else if (ch == '.' && saw_digit) {
+			if (octets == 4)
+				return (0);
+			*++tp = 0;
+			saw_digit = 0;
+		} else
+			return (0);
+	}
+	if (octets < 4)
+		return (0);
+
+	memcpy(dst, tmp, INADDRSZ);
+	return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *	convert presentation level address to network order binary form.
+ * return:
+ *	1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *	does not touch `dst' unless it's returning 1.
+ * credit:
+ *	inspired by Mark Andrews.
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, u_char *dst)
+{
+	static const char xdigits_l[] = "0123456789abcdef",
+			  xdigits_u[] = "0123456789ABCDEF";
+	u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+	const char *xdigits, *curtok;
+	int ch, saw_xdigit, count_xdigit;
+	u_int val;
+
+	memset((tp = tmp), '\0', IN6ADDRSZ);
+	endp = tp + IN6ADDRSZ;
+	colonp = NULL;
+	/* Leading :: requires some special handling. */
+	if (*src == ':')
+		if (*++src != ':')
+			return (0);
+	curtok = src;
+	saw_xdigit = count_xdigit = 0;
+	val = 0;
+	while ((ch = *src++) != '\0') {
+		const char *pch;
+
+		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+			pch = strchr((xdigits = xdigits_u), ch);
+		if (pch != NULL) {
+			if (count_xdigit >= 4)
+				return (0);
+			val <<= 4;
+			val |= (pch - xdigits);
+			if (val > 0xffff)
+				return (0);
+			saw_xdigit = 1;
+			count_xdigit++;
+			continue;
+		}
+		if (ch == ':') {
+			curtok = src;
+			if (!saw_xdigit) {
+				if (colonp)
+					return (0);
+				colonp = tp;
+				continue;
+			} else if (*src == '\0') {
+				return (0);
+			}
+			if (tp + INT16SZ > endp)
+				return (0);
+			*tp++ = (u_char) (val >> 8) & 0xff;
+			*tp++ = (u_char) val & 0xff;
+			saw_xdigit = 0;
+			count_xdigit = 0;
+			val = 0;
+			continue;
+		}
+		if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+		    inet_pton4(curtok, tp) > 0) {
+			tp += INADDRSZ;
+			saw_xdigit = 0;
+			count_xdigit = 0;
+			break;	/* '\0' was seen by inet_pton4(). */
+		}
+		return (0);
+	}
+	if (saw_xdigit) {
+		if (tp + INT16SZ > endp)
+			return (0);
+		*tp++ = (u_char) (val >> 8) & 0xff;
+		*tp++ = (u_char) val & 0xff;
+	}
+	if (colonp != NULL) {
+		/*
+		 * Since some memmove()'s erroneously fail to handle
+		 * overlapping regions, we'll do the shift by hand.
+		 */
+		const int n = tp - colonp;
+		int i;
+
+		if (tp == endp)
+			return (0);
+		for (i = 1; i <= n; i++) {
+			endp[- i] = colonp[n - i];
+			colonp[n - i] = 0;
+		}
+		tp = endp;
+	}
+	if (tp != endp)
+		return (0);
+	memcpy(dst, tmp, IN6ADDRSZ);
+	return (1);
+}
diff --git a/libc/upstream-openbsd/lib/libc/net/ntohl.c b/libc/upstream-openbsd/lib/libc/net/ntohl.c
new file mode 100644
index 0000000..36414b7
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/net/ntohl.c
@@ -0,0 +1,21 @@
+/*	$OpenBSD: ntohl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/types.h>
+#include <machine/endian.h>
+
+#undef ntohl
+
+u_int32_t
+ntohl(u_int32_t x)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+	u_char *s = (u_char *)&x;
+	return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
+#else
+	return x;
+#endif
+}
diff --git a/libc/upstream-openbsd/lib/libc/net/ntohs.c b/libc/upstream-openbsd/lib/libc/net/ntohs.c
new file mode 100644
index 0000000..8f345e8
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/net/ntohs.c
@@ -0,0 +1,21 @@
+/*	$OpenBSD: ntohs.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/types.h>
+#include <machine/endian.h>
+
+#undef ntohs
+
+u_int16_t
+ntohs(u_int16_t x)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+	u_char *s = (u_char *) &x;
+	return (u_int16_t)(s[0] << 8 | s[1]);
+#else
+	return x;
+#endif
+}
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
index 2178298..d78c819 100644
--- a/libc/zoneinfo/tzdata
+++ b/libc/zoneinfo/tzdata
Binary files differ
diff --git a/linker/Android.mk b/linker/Android.mk
index f0e6c13..d2bcfaf 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -6,6 +6,7 @@
     debugger.cpp \
     dlfcn.cpp \
     linker.cpp \
+    linker_allocator.cpp \
     linker_environ.cpp \
     linker_phdr.cpp \
     rt.cpp \
@@ -67,3 +68,5 @@
 LOCAL_INTERMEDIATE_TARGETS :=
 include $(LOCAL_PATH)/linker_executable.mk
 endif
+
+include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/linker/linker.cpp b/linker/linker.cpp
old mode 100755
new mode 100644
index b61e041..df53a84
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -48,6 +48,7 @@
 #include "linker_debug.h"
 #include "linker_environ.h"
 #include "linker_phdr.h"
+#include "linker_allocator.h"
 
 /* >>> IMPORTANT NOTE - READ ME BEFORE MODIFYING <<<
  *
@@ -69,14 +70,8 @@
 
 // We can't use malloc(3) in the dynamic linker. We use a linked list of anonymous
 // maps, each a single page in size. The pages are broken up into as many struct soinfo
-// objects as will fit, and they're all threaded together on a free list.
-#define SOINFO_PER_POOL ((PAGE_SIZE - sizeof(soinfo_pool_t*)) / sizeof(soinfo))
-struct soinfo_pool_t {
-  soinfo_pool_t* next;
-  soinfo info[SOINFO_PER_POOL];
-};
-static struct soinfo_pool_t* gSoInfoPools = NULL;
-static soinfo* gSoInfoFreeList = NULL;
+// objects as will fit.
+static LinkerAllocator<soinfo> gSoInfoAllocator;
 
 static soinfo* solist = &libdl_info;
 static soinfo* sonext = &libdl_info;
@@ -269,56 +264,13 @@
   rtld_db_dlactivity();
 }
 
-static bool ensure_free_list_non_empty() {
-  if (gSoInfoFreeList != NULL) {
-    return true;
-  }
-
-  // Allocate a new pool.
-  soinfo_pool_t* pool = reinterpret_cast<soinfo_pool_t*>(mmap(NULL, sizeof(*pool),
-                                                              PROT_READ|PROT_WRITE,
-                                                              MAP_PRIVATE|MAP_ANONYMOUS, 0, 0));
-  if (pool == MAP_FAILED) {
-    return false;
-  }
-
-  // Add the pool to our list of pools.
-  pool->next = gSoInfoPools;
-  gSoInfoPools = pool;
-
-  // Chain the entries in the new pool onto the free list.
-  gSoInfoFreeList = &pool->info[0];
-  soinfo* next = NULL;
-  for (int i = SOINFO_PER_POOL - 1; i >= 0; --i) {
-    pool->info[i].next = next;
-    next = &pool->info[i];
-  }
-
-  return true;
-}
-
-static void set_soinfo_pool_protection(int protection) {
-  for (soinfo_pool_t* p = gSoInfoPools; p != NULL; p = p->next) {
-    if (mprotect(p, sizeof(*p), protection) == -1) {
-      abort(); // Can't happen.
-    }
-  }
-}
-
 static soinfo* soinfo_alloc(const char* name) {
   if (strlen(name) >= SOINFO_NAME_LEN) {
     DL_ERR("library name \"%s\" too long", name);
     return NULL;
   }
 
-  if (!ensure_free_list_non_empty()) {
-    DL_ERR("out of memory when loading \"%s\"", name);
-    return NULL;
-  }
-
-  // Take the head element off the free list.
-  soinfo* si = gSoInfoFreeList;
-  gSoInfoFreeList = gSoInfoFreeList->next;
+  soinfo* si = gSoInfoAllocator.alloc();
 
   // Initialize the new element.
   memset(si, 0, sizeof(soinfo));
@@ -357,8 +309,8 @@
     if (si == sonext) {
         sonext = prev;
     }
-    si->next = gSoInfoFreeList;
-    gSoInfoFreeList = si;
+
+    gSoInfoAllocator.free(si);
 }
 
 
@@ -794,8 +746,8 @@
 
     munmap(reinterpret_cast<void*>(si->base), si->size);
     notify_gdb_of_unload(si);
-    soinfo_free(si);
     si->ref_count = 0;
+    soinfo_free(si);
   } else {
     si->ref_count--;
     TRACE("not unloading '%s', decrementing ref_count to %zd", si->name, si->ref_count);
@@ -822,19 +774,19 @@
     DL_ERR("invalid extended flags to android_dlopen_ext: %x", extinfo->flags);
     return NULL;
   }
-  set_soinfo_pool_protection(PROT_READ | PROT_WRITE);
+  gSoInfoAllocator.protect_all(PROT_READ | PROT_WRITE);
   soinfo* si = find_library(name, extinfo);
   if (si != NULL) {
     si->CallConstructors();
   }
-  set_soinfo_pool_protection(PROT_READ);
+  gSoInfoAllocator.protect_all(PROT_READ);
   return si;
 }
 
 int do_dlclose(soinfo* si) {
-  set_soinfo_pool_protection(PROT_READ | PROT_WRITE);
+  gSoInfoAllocator.protect_all(PROT_READ | PROT_WRITE);
   int result = soinfo_unload(si);
-  set_soinfo_pool_protection(PROT_READ);
+  gSoInfoAllocator.protect_all(PROT_READ);
   return result;
 }
 
@@ -1382,7 +1334,7 @@
 
   // The function may have called dlopen(3) or dlclose(3), so we need to ensure our data structures
   // are still writable. This happens with our debug malloc (see http://b/7941716).
-  set_soinfo_pool_protection(PROT_READ | PROT_WRITE);
+  gSoInfoAllocator.protect_all(PROT_READ | PROT_WRITE);
 }
 
 void soinfo::CallPreInitConstructors() {
@@ -1933,6 +1885,11 @@
       ldpreload_env = linker_env_get("LD_PRELOAD");
     }
 
+    // Linker does not call constructors for its own
+    // global variables so we need to initialize
+    // the allocator explicitly.
+    gSoInfoAllocator.init();
+
     INFO("[ android linker & debugger ]");
 
     soinfo* si = soinfo_alloc(args.argv[0]);
@@ -2150,7 +2107,7 @@
   args.abort_message_ptr = &gAbortMessage;
   ElfW(Addr) start_address = __linker_init_post_relocation(args, linker_addr);
 
-  set_soinfo_pool_protection(PROT_READ);
+  gSoInfoAllocator.protect_all(PROT_READ);
 
   // Return the address that the calling assembly stub should jump to.
   return start_address;
diff --git a/linker/linker_allocator.cpp b/linker/linker_allocator.cpp
new file mode 100644
index 0000000..60ce1ea
--- /dev/null
+++ b/linker/linker_allocator.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "linker_allocator.h"
+#include <inttypes.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+struct LinkerAllocatorPage {
+  LinkerAllocatorPage* next;
+  uint8_t bytes[PAGE_SIZE-sizeof(LinkerAllocatorPage*)];
+};
+
+struct FreeBlockInfo {
+  void* next_block;
+  size_t num_free_blocks;
+};
+
+LinkerBlockAllocator::LinkerBlockAllocator()
+  : block_size_(0),
+    page_list_(nullptr),
+    free_block_list_(nullptr)
+{}
+
+void LinkerBlockAllocator::init(size_t block_size) {
+  block_size_ = block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size;
+}
+
+
+void* LinkerBlockAllocator::alloc() {
+  if (free_block_list_ == nullptr) {
+    create_new_page();
+  }
+
+  FreeBlockInfo* block_info = reinterpret_cast<FreeBlockInfo*>(free_block_list_);
+  if (block_info->num_free_blocks > 1) {
+    FreeBlockInfo* next_block_info = reinterpret_cast<FreeBlockInfo*>(
+      reinterpret_cast<char*>(free_block_list_) + block_size_);
+    next_block_info->next_block = block_info->next_block;
+    next_block_info->num_free_blocks = block_info->num_free_blocks - 1;
+    free_block_list_ = next_block_info;
+  } else {
+    free_block_list_ = block_info->next_block;
+  }
+
+  block_info->next_block = nullptr;
+  block_info->num_free_blocks = 0;
+
+  return block_info;
+}
+
+void LinkerBlockAllocator::free(void* block) {
+  if (block == nullptr) {
+    return;
+  }
+
+  LinkerAllocatorPage* page = find_page(block);
+
+  if (page == nullptr) {
+    abort();
+  }
+
+  ssize_t offset = reinterpret_cast<uint8_t*>(block) - page->bytes;
+
+  if (offset % block_size_ != 0) {
+    abort();
+  }
+
+  FreeBlockInfo* block_info = reinterpret_cast<FreeBlockInfo*>(block);
+
+  block_info->next_block = free_block_list_;
+  block_info->num_free_blocks = 1;
+
+  free_block_list_ = block_info;
+}
+
+void LinkerBlockAllocator::protect_all(int prot) {
+  for (LinkerAllocatorPage* page = page_list_; page != nullptr; page = page->next) {
+    if (mprotect(page, PAGE_SIZE, prot) == -1) {
+      abort();
+    }
+  }
+}
+
+void LinkerBlockAllocator::create_new_page() {
+  LinkerAllocatorPage* page = reinterpret_cast<LinkerAllocatorPage*>(mmap(nullptr, PAGE_SIZE,
+      PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0));
+  if (page == MAP_FAILED) {
+    abort(); // oom
+  }
+
+  FreeBlockInfo* first_block = reinterpret_cast<FreeBlockInfo*>(page->bytes);
+  first_block->next_block = free_block_list_;
+  first_block->num_free_blocks = (PAGE_SIZE - sizeof(LinkerAllocatorPage*))/block_size_;
+
+  free_block_list_ = first_block;
+
+  page->next = page_list_;
+  page_list_ = page;
+}
+
+LinkerAllocatorPage* LinkerBlockAllocator::find_page(void* block) {
+  if (block == nullptr) {
+    abort();
+  }
+
+  LinkerAllocatorPage* page = page_list_;
+  const uint8_t* page_ptr = reinterpret_cast<const uint8_t*>(page);
+  while (page != nullptr) {
+    if (block >= (page_ptr + sizeof(page->next)) && block < (page_ptr + PAGE_SIZE)) {
+      return page;
+    }
+
+    page = page->next;
+  }
+
+  abort();
+}
diff --git a/linker/linker_allocator.h b/linker/linker_allocator.h
new file mode 100644
index 0000000..3af99da
--- /dev/null
+++ b/linker/linker_allocator.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LINKER_ALLOCATOR_H
+#define __LINKER_ALLOCATOR_H
+
+#include <stdlib.h>
+#include <limits.h>
+#include "private/bionic_macros.h"
+
+struct LinkerAllocatorPage;
+
+/*
+ * This class is a non-template version of the LinkerAllocator
+ * It keeps code inside .cpp file by keeping the interface
+ * template-free.
+ *
+ * Please use LinkerAllocator<type> where possible (everywhere).
+ */
+class LinkerBlockAllocator {
+ public:
+  LinkerBlockAllocator();
+
+  void init(size_t block_size);
+  void* alloc();
+  void free(void* block);
+  void protect_all(int prot);
+
+ private:
+  void create_new_page();
+  LinkerAllocatorPage* find_page(void* block);
+
+  size_t block_size_;
+  LinkerAllocatorPage* page_list_;
+  void* free_block_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(LinkerBlockAllocator);
+};
+
+/*
+ * A simple allocator for the dynamic linker. An allocator allocates instances
+ * of a single fixed-size type. Allocations are backed by page-sized private
+ * anonymous mmaps.
+ */
+template<typename T>
+class LinkerAllocator {
+ public:
+  LinkerAllocator() : block_allocator_() {}
+  void init() { block_allocator_.init(sizeof(T)); }
+  T* alloc() { return reinterpret_cast<T*>(block_allocator_.alloc()); }
+  void free(T* t) { block_allocator_.free(t); }
+  void protect_all(int prot) { block_allocator_.protect_all(prot); }
+ private:
+  LinkerBlockAllocator block_allocator_;
+  DISALLOW_COPY_AND_ASSIGN(LinkerAllocator);
+};
+#endif // __LINKER_ALLOCATOR_H
diff --git a/linker/tests/Android.mk b/linker/tests/Android.mk
new file mode 100644
index 0000000..600fe69
--- /dev/null
+++ b/linker/tests/Android.mk
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MULTILIB := both
+LOCAL_MODULE := linker-unit-tests
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+LOCAL_CFLAGS += -g -Wall -Wextra -Werror -std=gnu++11
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../libc/
+
+LOCAL_SRC_FILES := \
+  linker_allocator_test.cpp \
+  ../linker_allocator.cpp
+
+include $(BUILD_NATIVE_TEST)
+
+endif # !BUILD_TINY_ANDROID
diff --git a/linker/tests/linker_allocator_test.cpp b/linker/tests/linker_allocator_test.cpp
new file mode 100644
index 0000000..e3a91c5
--- /dev/null
+++ b/linker/tests/linker_allocator_test.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <gtest/gtest.h>
+
+#include "../linker_allocator.h"
+
+#include <unistd.h>
+
+namespace {
+
+struct test_struct_nominal {
+  void* pointer;
+  ssize_t value;
+};
+
+/*
+ * this one has size below allocator cap which is 2*sizeof(void*)
+ */
+struct test_struct_small {
+  char dummy_str[5];
+};
+
+/*
+ * 1009 byte struct (1009 is prime)
+ */
+struct test_struct_larger {
+  char dummy_str[1009];
+};
+
+static size_t kPageSize = sysconf(_SC_PAGE_SIZE);
+};
+
+TEST(linker_allocator, test_nominal) {
+  LinkerAllocator<test_struct_nominal> allocator;
+  allocator.init();
+
+  test_struct_nominal* ptr1 = allocator.alloc();
+  ASSERT_TRUE(ptr1 != nullptr);
+  test_struct_nominal* ptr2 = allocator.alloc();
+  ASSERT_TRUE(ptr2 != nullptr);
+  // they should be next to each other.
+  ASSERT_EQ(ptr1+1, ptr2);
+
+  ptr1->value = 42;
+
+  allocator.free(ptr1);
+  allocator.free(ptr2);
+}
+
+TEST(linker_allocator, test_small) {
+  LinkerAllocator<test_struct_small> allocator;
+  allocator.init();
+
+  char* ptr1 = reinterpret_cast<char*>(allocator.alloc());
+  char* ptr2 = reinterpret_cast<char*>(allocator.alloc());
+
+  ASSERT_TRUE(ptr1 != nullptr);
+  ASSERT_TRUE(ptr2 != nullptr);
+  ASSERT_EQ(ptr1+2*sizeof(void*), ptr2);
+}
+
+TEST(linker_allocator, test_larger) {
+  LinkerAllocator<test_struct_larger> allocator;
+  allocator.init();
+
+  test_struct_larger* ptr1 = allocator.alloc();
+  test_struct_larger* ptr2 = allocator.alloc();
+
+  ASSERT_TRUE(ptr1 != nullptr);
+  ASSERT_TRUE(ptr2 != nullptr);
+
+  ASSERT_EQ(ptr1+1, ptr2);
+
+  // lets allocate until we reach next page.
+  size_t n = kPageSize/sizeof(test_struct_larger) + 1 - 2;
+
+  for (size_t i=0; i<n; ++i) {
+    ASSERT_TRUE(allocator.alloc() != nullptr);
+  }
+
+}
+
+static void protect_all() {
+  LinkerAllocator<test_struct_larger> allocator;
+  allocator.init();
+
+  // number of allocs to reach the end of first page
+  size_t n = kPageSize/sizeof(test_struct_larger) - 1;
+  test_struct_larger* page1_ptr = allocator.alloc();
+
+  for (size_t i=0; i<n; ++i) {
+    allocator.alloc();
+  }
+
+  test_struct_larger* page2_ptr = allocator.alloc();
+  allocator.protect_all(PROT_READ);
+  allocator.protect_all(PROT_READ | PROT_WRITE);
+  // check access
+  page2_ptr->dummy_str[23] = 27;
+  page1_ptr->dummy_str[13] = 11;
+
+  allocator.protect_all(PROT_READ);
+  fprintf(stderr, "trying to access protected page");
+
+  // this should result in segmentation fault
+  page1_ptr->dummy_str[11] = 7;
+}
+
+TEST(linker_allocator, test_protect) {
+  testing::FLAGS_gtest_death_test_style = "threadsafe";
+  ASSERT_EXIT(protect_all(), testing::KilledBySignal(SIGSEGV), "trying to access protected page");
+}
+
diff --git a/tests/Android.mk b/tests/Android.mk
index 10e288c..4ad07ba 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -44,6 +44,7 @@
     -std=gnu++11 \
 
 libBionicStandardTests_src_files := \
+    arpa_inet_test.cpp \
     buffer_tests.cpp \
     ctype_test.cpp \
     dirent_test.cpp \
@@ -59,6 +60,7 @@
     locale_test.cpp \
     malloc_test.cpp \
     math_test.cpp \
+    mntent_test.cpp \
     netdb_test.cpp \
     pthread_test.cpp \
     regex_test.cpp \
diff --git a/tests/arpa_inet_test.cpp b/tests/arpa_inet_test.cpp
new file mode 100644
index 0000000..5e53337
--- /dev/null
+++ b/tests/arpa_inet_test.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <arpa/inet.h>
+
+TEST(arpa_inet, inet_addr) {
+  ASSERT_EQ((htonl)(0x7f000001), inet_addr("127.0.0.1"));
+}
+
+TEST(arpa_inet, inet_aton) {
+  in_addr a;
+  ASSERT_EQ(1, inet_aton("127.0.0.1", &a));
+  ASSERT_EQ((htonl)(0x7f000001), a.s_addr);
+}
+
+TEST(arpa_inet, inet_lnaof) {
+  in_addr a = { htonl(0x12345678) };
+  ASSERT_EQ(0x00345678U, inet_lnaof(a));
+}
+
+TEST(arpa_inet, inet_makeaddr) {
+  in_addr a = inet_makeaddr(0x12U, 0x345678);
+  ASSERT_EQ((htonl)(0x12345678), a.s_addr);
+}
+
+TEST(arpa_inet, inet_netof) {
+  in_addr a = { htonl(0x12345678) };
+  ASSERT_EQ(0x12U, inet_netof(a));
+}
+
+TEST(arpa_inet, inet_network) {
+  ASSERT_EQ(0x7f000001U, inet_network("127.0.0.1"));
+}
+
+TEST(arpa_inet, inet_ntoa) {
+  in_addr a = { (htonl)(0x7f000001) };
+  ASSERT_STREQ("127.0.0.1", inet_ntoa(a));
+}
+
+TEST(arpa_inet, inet_pton__inet_ntop) {
+  sockaddr_storage ss;
+  ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &ss));
+
+  char s[INET_ADDRSTRLEN];
+  ASSERT_STREQ("127.0.0.1", inet_ntop(AF_INET, &ss, s, INET_ADDRSTRLEN));
+}
+
+TEST(arpa_inet, inet_ntop_overflow) {
+  // OpenBSD's inet_ntop had a bug where passing a 'size' larger than INET_ADDRSTRLEN
+  // for AF_INET or INET6_ADDRSTRLEN for AF_INET6 would cause inet_ntop to overflow an
+  // internal buffer.
+
+  sockaddr_storage ss4;
+  ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &ss4));
+
+  sockaddr_storage ss6;
+  ASSERT_EQ(1, inet_pton(AF_INET6, "::1", &ss6));
+
+  char s4[INET_ADDRSTRLEN];
+  char s6[INET6_ADDRSTRLEN];
+  ASSERT_STREQ("127.0.0.1", inet_ntop(AF_INET, &ss4, s4, INET_ADDRSTRLEN));
+  ASSERT_STREQ("127.0.0.1", inet_ntop(AF_INET, &ss4, s4, 2*INET_ADDRSTRLEN));
+  ASSERT_STREQ("::1", inet_ntop(AF_INET6, &ss6, s6, INET_ADDRSTRLEN));
+  ASSERT_STREQ("::1", inet_ntop(AF_INET6, &ss6, s6, INET6_ADDRSTRLEN));
+  ASSERT_STREQ("::1", inet_ntop(AF_INET6, &ss6, s6, 2*INET6_ADDRSTRLEN));
+}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 1fdecdb..b31d7e4 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -53,7 +53,7 @@
 TEST(dlfcn, dlopen_failure) {
   void* self = dlopen("/does/not/exist", RTLD_NOW);
   ASSERT_TRUE(self == NULL);
-#if __BIONIC__
+#if defined(__BIONIC__)
   ASSERT_STREQ("dlopen failed: library \"/does/not/exist\" not found", dlerror());
 #else
   ASSERT_STREQ("/does/not/exist: cannot open shared object file: No such file or directory", dlerror());
@@ -92,14 +92,14 @@
   // NULL handle.
   sym = dlsym(NULL, "test");
   ASSERT_TRUE(sym == NULL);
-#if __BIONIC__
+#if defined(__BIONIC__)
   ASSERT_SUBSTR("dlsym library handle is null", dlerror());
 #else
   ASSERT_SUBSTR("undefined symbol: test", dlerror()); // glibc isn't specific about the failure.
 #endif
 
   // NULL symbol name.
-#if __BIONIC__
+#if defined(__BIONIC__)
   // glibc marks this parameter non-null and SEGVs if you cheat.
   sym = dlsym(self, NULL);
   ASSERT_TRUE(sym == NULL);
@@ -206,7 +206,7 @@
   dlerror(); // Clear any pending errors.
   void* handle;
 
-#ifdef __GLIBC__
+#if defined(__GLIBC__)
   // glibc was smart enough not to define RTLD_NOW as 0, so it can detect missing flags.
   handle = dlopen(NULL, 0);
   ASSERT_TRUE(handle == NULL);
diff --git a/tests/fcntl_test.cpp b/tests/fcntl_test.cpp
index 725ac4a..fb6b07e 100644
--- a/tests/fcntl_test.cpp
+++ b/tests/fcntl_test.cpp
@@ -73,7 +73,7 @@
 TEST(fcntl, fallocate_EINVAL) {
   TemporaryFile tf;
 
-#if !defined(__GLIBC__)
+#if defined(__BIONIC__)
   errno = 0;
   ASSERT_EQ(-1, fallocate(tf.fd, 0, 0, -1));
   ASSERT_EQ(EINVAL, errno);
@@ -98,7 +98,7 @@
   ASSERT_EQ(0, fstat(tf.fd, &sb));
   ASSERT_EQ(0, sb.st_size);
 
-#if !defined(__GLIBC__)
+#if defined(__BIONIC__)
   ASSERT_EQ(0, fallocate(tf.fd, 0, 0, 1));
   ASSERT_EQ(0, fstat(tf.fd, &sb));
   ASSERT_EQ(1, sb.st_size);
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index e0d055e..873c71e 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -668,7 +668,7 @@
 }
 
 TEST(DEATHTEST, FD_ISSET_fortified) {
-#ifdef __BIONIC__ // glibc catches this at compile-time.
+#if defined(__BIONIC__) // glibc catches this at compile-time.
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   fd_set set;
   memset(&set, 0, sizeof(set));
diff --git a/tests/locale_test.cpp b/tests/locale_test.cpp
index 347b5b1..7d063f9 100644
--- a/tests/locale_test.cpp
+++ b/tests/locale_test.cpp
@@ -58,7 +58,7 @@
   EXPECT_EQ(NULL, setlocale(13, NULL));
   EXPECT_EQ(EINVAL, errno);
 
-#if __BIONIC__
+#if defined(__BIONIC__)
   // The "" locale is implementation-defined. For bionic, it's the C locale.
   // glibc will give us something like "en_US.UTF-8", depending on the user's configuration.
   EXPECT_STREQ("C", setlocale(LC_ALL, ""));
diff --git a/tests/mntent_test.cpp b/tests/mntent_test.cpp
new file mode 100644
index 0000000..637cb52
--- /dev/null
+++ b/tests/mntent_test.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <mntent.h>
+
+TEST(mntent, mntent_smoke) {
+  FILE* fp = setmntent("/no/mnt/tab/on/android", "r");
+  ASSERT_TRUE(fp == NULL);
+
+#if __BIONIC__ // glibc doesn't let you call getmntent/getmntent_r with a NULL FILE*.
+  ASSERT_TRUE(getmntent(fp) == NULL);
+
+  struct mntent mbuf;
+  char cbuf[32];
+  ASSERT_TRUE(getmntent_r(fp, &mbuf, cbuf, sizeof(cbuf)) == NULL);
+#endif
+
+  ASSERT_EQ(1, endmntent(fp));
+}
diff --git a/tests/regex_test.cpp b/tests/regex_test.cpp
index 659d1db..d026221 100644
--- a/tests/regex_test.cpp
+++ b/tests/regex_test.cpp
@@ -28,7 +28,7 @@
 
   char buf[80];
   regerror(REG_NOMATCH, &re, buf, sizeof(buf));
-#if __BIONIC__
+#if defined(__BIONIC__)
   ASSERT_STREQ("regexec() failed to match", buf);
 #else
   ASSERT_STREQ("No match", buf);
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 7c19962..caf4c65 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -21,7 +21,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
-#ifdef __BIONIC__
+#if defined(__BIONIC__)
 static int child_fn(void* i_ptr) {
   *reinterpret_cast<int*>(i_ptr) = 42;
   return 123;
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 4725350..655ad3f 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -219,7 +219,7 @@
 }
 
 TEST(stdio, snprintf_n) {
-#if !defined(__GLIBC__)
+#if defined(__BIONIC__)
   // http://b/14492135
   char buf[32];
   int i = 1234;
@@ -460,7 +460,7 @@
 
   errno = 0;
   EXPECT_EQ(EOF, fwprintf(fp, L"hello"));
-#if !defined(__GLIBC__)
+#if defined(__BIONIC__)
   EXPECT_EQ(EBADF, errno);
 #endif
 
@@ -478,7 +478,7 @@
 
   errno = 0;
   EXPECT_EQ(WEOF, fputwc(L'x', fp));
-#if !defined(__GLIBC__)
+#if defined(__BIONIC__)
   EXPECT_EQ(EBADF, errno);
 #endif
 }
@@ -521,7 +521,7 @@
   ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp)));
   EXPECT_EQ(0, fgetpos(fp, &pos5));
 
-#ifdef __BIONIC__
+#if defined(__BIONIC__)
   // Bionic's fpos_t is just an alias for off_t. This is inherited from OpenBSD
   // upstream. Glibc differs by storing the mbstate_t inside its fpos_t. In
   // Bionic (and upstream OpenBSD) the mbstate_t is stored inside the FILE
@@ -586,9 +586,9 @@
   // Store the "inside multi byte" position.
   fpos_t pos_inside_mb;
   ASSERT_EQ(0, fgetpos(fp, &pos_inside_mb));
-  #ifdef __BIONIC__
-    ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb));
-  #endif
+#if defined(__BIONIC__)
+  ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb));
+#endif
 
   // Reading from within a byte should produce an error.
   ASSERT_EQ(WEOF, fgetwc(fp));
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index fc0f0e1..978a60f 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -42,7 +42,7 @@
   EXPECT_EQ(902267124, lrand48());
   EXPECT_EQ(132366131, lrand48());
 
-#if __BIONIC__
+#if defined(__BIONIC__)
   // On bionic, random(3) is equivalent to lrand48...
   srandom(0x01020304);
   EXPECT_EQ(1409163720, random());
diff --git a/tests/sys_resource_test.cpp b/tests/sys_resource_test.cpp
index bd974cb..d6d99a0 100644
--- a/tests/sys_resource_test.cpp
+++ b/tests/sys_resource_test.cpp
@@ -18,7 +18,7 @@
 
 #include <sys/resource.h>
 
-#if __GLIBC__
+#if defined(__GLIBC__)
 /* The host glibc we're currently building with doesn't have prlimit64 yet. */
 static int prlimit64(pid_t, int resource, const struct rlimit64* new_limit, struct rlimit64* old_limit) {
   if (new_limit != NULL) {
@@ -30,7 +30,7 @@
 #endif
 
 TEST(sys_resource, smoke) {
-#if __LP64__ || __GLIBC__
+#if defined(__LP64__) || defined(__GLIBC__)
   ASSERT_EQ(sizeof(rlimit), sizeof(rlimit64));
   ASSERT_EQ(8U, sizeof(rlim_t));
 #else
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 2b51aad..ff05039 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -67,7 +67,7 @@
   ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(-(current_brk + 1)));
   ASSERT_EQ(ENOMEM, errno);
 
-#if !defined(__GLIBC__)
+#if defined(__BIONIC__)
   // The maximum negative value is an interesting special case that glibc gets wrong.
   ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN));
   ASSERT_EQ(ENOMEM, errno);
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 30d7bff..c8aec2d 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -288,7 +288,7 @@
   // 4-byte UTF-8.
   ASSERT_EQ(4U, mbrtowc(out, "\xf0\xa4\xad\xa2" "ef", 6, NULL));
   ASSERT_EQ(static_cast<wchar_t>(0x24b62), out[0]);
-#if __BIONIC__ // glibc allows this.
+#if defined(__BIONIC__) // glibc allows this.
   // Illegal 5-byte UTF-8.
   ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf8\xa1\xa2\xa3\xa4" "f", 6, NULL));
   ASSERT_EQ(EILSEQ, errno);