Merge changes Ife4692e4,I7304cc1d,If19653d0,I769ca792,I93625d19, ...

* changes:
  Move <sys/sysconf.h> to <bits/sysconf.h>.
  Remove mbstowcs from <wchar.h>.
  Extract getopt and friends to <bits/getopt.h>
  Remove declaration of unlinkat from <fcntl.h>.
  Extract ioctl to <bits/ioctl.h>.
  Extract fcntl to <bits/fcntl.h>.
  Extract strcasecmp and friends to <bits/strcasecmp.h>.
  Make <bits/lockf.h> compile standalone.
  Make <android/dlext.h> compile standalone.
  Make the network headers compile standalone.
  Remove duplicate declaration of mlock, munlock.
diff --git a/libc/Android.bp b/libc/Android.bp
index 7c82695..3ec5e96 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -414,6 +414,7 @@
         "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/base64.c",
         "upstream-openbsd/lib/libc/net/htonl.c",
         "upstream-openbsd/lib/libc/net/htons.c",
         "upstream-openbsd/lib/libc/net/inet_lnaof.c",
@@ -1316,6 +1317,7 @@
         "bionic/NetdClientDispatch.cpp",
         "bionic/net_if.cpp",
         "bionic/netinet_in.cpp",
+        "bionic/nl_types.cpp",
         "bionic/open.cpp",
         "bionic/pathconf.cpp",
         "bionic/pause.cpp",
diff --git a/libc/Android.mk b/libc/Android.mk
index 631de5e..fa392d1 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -145,6 +145,7 @@
     bionic/NetdClientDispatch.cpp \
     bionic/net_if.cpp \
     bionic/netinet_in.cpp \
+    bionic/nl_types.cpp \
     bionic/open.cpp \
     bionic/pathconf.cpp \
     bionic/pause.cpp \
@@ -406,6 +407,7 @@
     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/base64.c \
     upstream-openbsd/lib/libc/net/htonl.c \
     upstream-openbsd/lib/libc/net/htons.c \
     upstream-openbsd/lib/libc/net/inet_lnaof.c \
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 1cabab4..d75b94d 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -312,27 +312,34 @@
   }
 }
 
+// oem_XXXX -> uid
+//  Supported ranges:
+//   AID_OEM_RESERVED_START to AID_OEM_RESERVED_END (2900-2999)
+//   AID_OEM_RESERVED_2_START to AID_OEM_RESERVED_2_END (5000-5999)
+// Check OEM id is within range.
+static bool is_oem_id(id_t id) {
+  return (((id >= AID_OEM_RESERVED_START) && (id <= AID_OEM_RESERVED_END)) ||
+      ((id >= AID_OEM_RESERVED_2_START) && (id <= AID_OEM_RESERVED_2_END)));
+}
+
 // Translate an OEM name to the corresponding user/group id.
-// oem_XXX -> AID_OEM_RESERVED_2_START + XXX, iff XXX is within range.
 static id_t oem_id_from_name(const char* name) {
   unsigned int id;
   if (sscanf(name, "oem_%u", &id) != 1) {
     return 0;
   }
-  // Check OEM id is within range.
-  if (id > (AID_OEM_RESERVED_2_END - AID_OEM_RESERVED_2_START)) {
+  if (!is_oem_id(id)) {
     return 0;
   }
-  return AID_OEM_RESERVED_2_START + static_cast<id_t>(id);
+  return static_cast<id_t>(id);
 }
 
 static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
-  if (uid < AID_OEM_RESERVED_2_START || uid > AID_OEM_RESERVED_2_END) {
+  if (!is_oem_id(uid)) {
     return NULL;
   }
 
-  snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u",
-           uid - AID_OEM_RESERVED_2_START);
+  snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u", uid);
   snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
   snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
 
@@ -346,12 +353,12 @@
 }
 
 static group* oem_id_to_group(gid_t gid, group_state_t* state) {
-  if (gid < AID_OEM_RESERVED_2_START || gid > AID_OEM_RESERVED_2_END) {
+  if (!is_oem_id(gid)) {
     return NULL;
   }
 
   snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_),
-           "oem_%u", gid - AID_OEM_RESERVED_2_START);
+           "oem_%u", gid);
 
   group* gr = &state->group_;
   gr->gr_name   = state->group_name_buffer_;
diff --git a/libc/bionic/nl_types.cpp b/libc/bionic/nl_types.cpp
new file mode 100644
index 0000000..2cde591
--- /dev/null
+++ b/libc/bionic/nl_types.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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 <nl_types.h>
+
+#include <errno.h>
+
+nl_catd catopen(const char*, int) {
+  return reinterpret_cast<nl_catd>(-1);
+}
+
+char* catgets(nl_catd, int, int, const char* message) {
+  return const_cast<char*>(message);
+}
+
+int catclose(nl_catd) {
+  // Since we didn't hand out a valid nl_catd, you can't be returning one to us.
+  errno = EBADF;
+  return -1;
+}
diff --git a/libc/include/nl_types.h b/libc/include/nl_types.h
new file mode 100644
index 0000000..84227bd
--- /dev/null
+++ b/libc/include/nl_types.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef _NL_TYPES_H_
+#define _NL_TYPES_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#define NL_CAT_LOCALE 1
+#define NL_SETD 1
+
+typedef void* nl_catd;
+typedef int nl_item;
+
+nl_catd catopen(const char*, int);
+char* catgets(nl_catd, int, int, const char*);
+int catclose(nl_catd);
+
+__END_DECLS
+
+#endif
diff --git a/libc/libc.arm.brillo.map b/libc/libc.arm.brillo.map
index 666d752..651fea4 100644
--- a/libc/libc.arm.brillo.map
+++ b/libc/libc.arm.brillo.map
@@ -1273,6 +1273,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index fa83528..1c7a0ba 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1273,6 +1273,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index c9f5213..7daa557 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1195,6 +1195,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 49572a0..ed20efc 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1299,6 +1299,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.mips.brillo.map b/libc/libc.mips.brillo.map
index 83a6f74..d96de34 100644
--- a/libc/libc.mips.brillo.map
+++ b/libc/libc.mips.brillo.map
@@ -1257,6 +1257,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 1a3e56b..5fe3a51 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1257,6 +1257,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index c9f5213..7daa557 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1195,6 +1195,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.x86.brillo.map b/libc/libc.x86.brillo.map
index cee82c2..f167183 100644
--- a/libc/libc.x86.brillo.map
+++ b/libc/libc.x86.brillo.map
@@ -1256,6 +1256,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 9b65cbf..d37d28a 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1256,6 +1256,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index c9f5213..7daa557 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1195,6 +1195,9 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
index c5dbdcf..43531c0 100755
--- a/libc/tools/check-symbols-glibc.py
+++ b/libc/tools/check-symbols-glibc.py
@@ -178,6 +178,23 @@
   '_ctype_',
   '__libc_init',
 ])
+# POSIX has some stuff that's too stupid for words (a64l) or not actually
+# implemented in glibc unless you count always failing with ENOSYS as
+# being implemented (fattach).
+in_posix_and_glibc_but_actually_dead = set([
+  'a64l',
+  'fattach',
+  'fdetach',
+  'getmsg',
+  'getpmsg',
+  'isastream',
+  'l64a',
+  'putmsg',
+  'putpmsg',
+])
+
+posix = posix - in_posix_and_glibc_but_actually_dead
+glibc = glibc - in_posix_and_glibc_but_actually_dead
 
 if not only_unwanted:
   #print 'glibc:'
diff --git a/libc/dns/net/base64.c b/libc/upstream-openbsd/lib/libc/net/base64.c
similarity index 82%
rename from libc/dns/net/base64.c
rename to libc/upstream-openbsd/lib/libc/net/base64.c
index 1886986..e90696d 100644
--- a/libc/dns/net/base64.c
+++ b/libc/upstream-openbsd/lib/libc/net/base64.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: base64.c,v 1.8 2002/11/11 01:15:17 thorpej Exp $	*/
+/*	$OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $	*/
 
 /*
  * Copyright (c) 1996 by Internet Software Consortium.
@@ -42,25 +42,14 @@
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
  */
 
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: base64.c,v 1.8 2002/11/11 01:15:17 thorpej Exp $");
-#endif /* LIBC_SCCS and not lint */
-
 #include <sys/types.h>
-#include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 
-#include <assert.h>
 #include <ctype.h>
-#ifdef ANDROID_CHANGES
-#include "resolv_private.h"
-#else
 #include <resolv.h>
-#endif
 #include <stdio.h>
 
 #include <stdlib.h>
@@ -118,9 +107,9 @@
    end of the data is performed using the '=' character.
 
    Since all base64 input is an integral number of octets, only the
-         -------------------------------------------------
+         -------------------------------------------------                       
    following cases can arise:
-
+   
        (1) the final quantum of encoding input is an integral
            multiple of 24 bits; here, the final unit of encoded
 	   output will be an integral multiple of 4 characters
@@ -141,12 +130,9 @@
 	size_t targsize;
 {
 	size_t datalength = 0;
-	u_char input[3] = { 0, 0, 0 };  /* make compiler happy */
+	u_char input[3];
 	u_char output[4];
-	size_t i;
-
-	assert(src != NULL);
-	assert(target != NULL);
+	int i;
 
 	while (2 < srclength) {
 		input[0] = *src++;
@@ -154,16 +140,10 @@
 		input[2] = *src++;
 		srclength -= 3;
 
-		output[0] = (u_int32_t)input[0] >> 2;
-		output[1] = ((u_int32_t)(input[0] & 0x03) << 4) +
-		    ((u_int32_t)input[1] >> 4);
-		output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) +
-		    ((u_int32_t)input[2] >> 6);
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
 		output[3] = input[2] & 0x3f;
-		assert(output[0] < 64);
-		assert(output[1] < 64);
-		assert(output[2] < 64);
-		assert(output[3] < 64);
 
 		if (datalength + 4 > targsize)
 			return (-1);
@@ -172,22 +152,17 @@
 		target[datalength++] = Base64[output[2]];
 		target[datalength++] = Base64[output[3]];
 	}
-
+    
 	/* Now we worry about padding. */
 	if (0 != srclength) {
 		/* Get what's left. */
 		input[0] = input[1] = input[2] = '\0';
 		for (i = 0; i < srclength; i++)
 			input[i] = *src++;
-
-		output[0] = (u_int32_t)input[0] >> 2;
-		output[1] = ((u_int32_t)(input[0] & 0x03) << 4) +
-		    ((u_int32_t)input[1] >> 4);
-		output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) +
-		    ((u_int32_t)input[2] >> 6);
-		assert(output[0] < 64);
-		assert(output[1] < 64);
-		assert(output[2] < 64);
+	
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
 
 		if (datalength + 4 > targsize)
 			return (-1);
@@ -217,17 +192,14 @@
 	u_char *target;
 	size_t targsize;
 {
-	size_t tarindex;
-	int state, ch;
+	int tarindex, state, ch;
+	u_char nextbyte;
 	char *pos;
 
-	assert(src != NULL);
-	assert(target != NULL);
-
 	state = 0;
 	tarindex = 0;
 
-	while ((ch = (u_char) *src++) != '\0') {
+	while ((ch = (unsigned char)*src++) != '\0') {
 		if (isspace(ch))	/* Skip whitespace anywhere. */
 			continue;
 
@@ -249,24 +221,28 @@
 			break;
 		case 1:
 			if (target) {
-				if (tarindex + 1 >= targsize)
+				if (tarindex >= targsize)
 					return (-1);
-				target[tarindex] |=
-				    (u_int32_t)(pos - Base64) >> 4;
-				target[tarindex+1]  = ((pos - Base64) & 0x0f)
-							<< 4 ;
+				target[tarindex]   |=  (pos - Base64) >> 4;
+				nextbyte = ((pos - Base64) & 0x0f) << 4;
+				if (tarindex + 1 < targsize)
+					target[tarindex+1] = nextbyte;
+				else if (nextbyte)
+					return (-1);
 			}
 			tarindex++;
 			state = 2;
 			break;
 		case 2:
 			if (target) {
-				if (tarindex + 1 >= targsize)
+				if (tarindex >= targsize)
 					return (-1);
-				target[tarindex] |=
-					(u_int32_t)(pos - Base64) >> 2;
-				target[tarindex+1] = ((pos - Base64) & 0x03)
-							<< 6;
+				target[tarindex]   |=  (pos - Base64) >> 2;
+				nextbyte = ((pos - Base64) & 0x03) << 6;
+				if (tarindex + 1 < targsize)
+					target[tarindex+1] = nextbyte;
+				else if (nextbyte)
+					return (-1);
 			}
 			tarindex++;
 			state = 3;
@@ -280,8 +256,6 @@
 			tarindex++;
 			state = 0;
 			break;
-		default:
-			abort();
 		}
 	}
 
@@ -290,8 +264,8 @@
 	 * on a byte boundary, and/or with erroneous trailing characters.
 	 */
 
-	if (ch == Pad64) {		/* We got a pad char. */
-		ch = *src++;		/* Skip it, get next. */
+	if (ch == Pad64) {			/* We got a pad char. */
+		ch = (unsigned char)*src++;	/* Skip it, get next. */
 		switch (state) {
 		case 0:		/* Invalid = in first position */
 		case 1:		/* Invalid = in second position */
@@ -299,13 +273,13 @@
 
 		case 2:		/* Valid, means one byte of info */
 			/* Skip any number of spaces. */
-			for (; ch != '\0'; ch = (u_char) *src++)
+			for (; ch != '\0'; ch = (unsigned char)*src++)
 				if (!isspace(ch))
 					break;
 			/* Make sure there is another trailing = sign. */
 			if (ch != Pad64)
 				return (-1);
-			ch = *src++;		/* Skip the = */
+			ch = (unsigned char)*src++;		/* Skip the = */
 			/* Fall through to "single trailing =" case. */
 			/* FALLTHROUGH */
 
@@ -314,7 +288,7 @@
 			 * We know this char is an =.  Is there anything but
 			 * whitespace after it?
 			 */
-			for (; ch != '\0'; ch = (u_char) *src++)
+			for (; ch != '\0'; ch = (unsigned char)*src++)
 				if (!isspace(ch))
 					return (-1);
 
@@ -324,7 +298,8 @@
 			 * zeros.  If we don't check them, they become a
 			 * subliminal channel.
 			 */
-			if (target && target[tarindex] != 0)
+			if (target && tarindex < targsize &&
+			    target[tarindex] != 0)
 				return (-1);
 		}
 	} else {
diff --git a/tests/Android.mk b/tests/Android.mk
index 1582f3b..7292d9d 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -74,9 +74,11 @@
     net_if_test.cpp \
     netinet_in_test.cpp \
     netinet_udp_test.cpp \
+    nl_types_test.cpp \
     pthread_test.cpp \
     pty_test.cpp \
     regex_test.cpp \
+    resolv_test.cpp \
     sched_test.cpp \
     search_test.cpp \
     semaphore_test.cpp \
@@ -414,7 +416,7 @@
     libcutils \
 
 bionic-unit-tests-glibc_ldlibs := \
-    -lrt -ldl -lutil \
+    -lresolv -lrt -ldl -lutil \
 
 bionic-unit-tests-glibc_c_includes := \
     bionic/libc \
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index c81ca58..29cd907 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -122,12 +122,20 @@
   check_get_passwd("radio", 1001, TYPE_SYSTEM);
 }
 
-TEST(getpwnam, oem_id_0) {
-  check_get_passwd("oem_0", 5000, TYPE_SYSTEM);
+TEST(getpwnam, oem_id_5000) {
+  check_get_passwd("oem_5000", 5000, TYPE_SYSTEM);
 }
 
-TEST(getpwnam, oem_id_999) {
-  check_get_passwd("oem_999", 5999, TYPE_SYSTEM);
+TEST(getpwnam, oem_id_5999) {
+  check_get_passwd("oem_5999", 5999, TYPE_SYSTEM);
+}
+
+TEST(getpwnam, oem_id_2900) {
+  check_get_passwd("oem_2900", 2900, TYPE_SYSTEM);
+}
+
+TEST(getpwnam, oem_id_2999) {
+  check_get_passwd("oem_2999", 2999, TYPE_SYSTEM);
 }
 
 TEST(getpwnam, app_id_nobody) {
@@ -255,12 +263,20 @@
   check_get_group("radio", 1001);
 }
 
-TEST(getgrnam, oem_id_0) {
-  check_get_group("oem_0", 5000);
+TEST(getgrnam, oem_id_5000) {
+  check_get_group("oem_5000", 5000);
 }
 
-TEST(getgrnam, oem_id_999) {
-  check_get_group("oem_999", 5999);
+TEST(getgrnam, oem_id_5999) {
+  check_get_group("oem_5999", 5999);
+}
+
+TEST(getgrnam, oem_id_2900) {
+  check_get_group("oem_2900", 2900);
+}
+
+TEST(getgrnam, oem_id_2999) {
+  check_get_group("oem_2999", 2999);
 }
 
 TEST(getgrnam, app_id_nobody) {
diff --git a/tests/nl_types_test.cpp b/tests/nl_types_test.cpp
new file mode 100644
index 0000000..2e3995b
--- /dev/null
+++ b/tests/nl_types_test.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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 <nl_types.h>
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+TEST(nl_types, smoke) {
+  nl_catd cat = catopen("/does/not/exist", NL_CAT_LOCALE);
+  ASSERT_EQ(reinterpret_cast<nl_catd>(-1), cat);
+
+  ASSERT_STREQ("hello, world!", catgets(cat, NL_SETD, 0, "hello, world!"));
+
+  errno = 0;
+  ASSERT_EQ(-1, catclose(cat));
+  ASSERT_EQ(EBADF, errno);
+}
diff --git a/tests/resolv_test.cpp b/tests/resolv_test.cpp
new file mode 100644
index 0000000..08f9d90
--- /dev/null
+++ b/tests/resolv_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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 <resolv.h>
+
+#include <gtest/gtest.h>
+
+TEST(resolv, b64_pton_28035006) {
+  // Test data from https://groups.google.com/forum/#!topic/mailing.openbsd.tech/w3ACIlklJkI.
+  const char* data =
+      "p1v3+nehH3N3n+/OokzXpsyGF2VVpxIxkjSn3Mv/Sq74OE1iFuVU+K4bQImuVj"
+      "S55RB2fpCpbB8Nye7tzrt6h9YPP3yyJfqORDETGmIB4lveZXA4KDxx50F9rYrO"
+      "dFbTLyWfNBb/8Q2TnD72eY/3Y5P9qwtJwyDL25Tleic8G3g=";
+
+  // This buffer is exactly the right size, but old versions of the BSD code
+  // incorrectly required an extra byte. http://b/28035006.
+  uint8_t buf[128];
+  ASSERT_EQ(128, b64_pton(data, buf, sizeof(buf)));
+}