Merge "Pass around struct android_net_context for better behaviour"
diff --git a/libc/include/sysexits.h b/libc/include/sysexits.h
new file mode 100644
index 0000000..e244836
--- /dev/null
+++ b/libc/include/sysexits.h
@@ -0,0 +1,119 @@
+/*	$OpenBSD: sysexits.h,v 1.5 2003/06/02 19:34:12 millert Exp $	*/
+/*	$NetBSD: sysexits.h,v 1.4 1994/10/26 00:56:33 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)sysexits.h	4.8 (Berkeley) 4/3/91
+ */
+
+#ifndef	_SYSEXITS_H_
+#define	_SYSEXITS_H_
+
+/*
+ *  SYSEXITS.H -- Exit status codes for system programs.
+ *
+ *	This include file attempts to categorize possible error
+ *	exit statuses for system programs, notably delivermail
+ *	and the Berkeley network.
+ *
+ *	Error numbers begin at EX__BASE to reduce the possibility of
+ *	clashing with other exit statuses that random programs may
+ *	already return.  The meaning of the codes is approximately
+ *	as follows:
+ *
+ *	EX_USAGE -- The command was used incorrectly, e.g., with
+ *		the wrong number of arguments, a bad flag, a bad
+ *		syntax in a parameter, or whatever.
+ *	EX_DATAERR -- The input data was incorrect in some way.
+ *		This should only be used for user's data & not
+ *		system files.
+ *	EX_NOINPUT -- An input file (not a system file) did not
+ *		exist or was not readable.  This could also include
+ *		errors like "No message" to a mailer (if it cared
+ *		to catch it).
+ *	EX_NOUSER -- The user specified did not exist.  This might
+ *		be used for mail addresses or remote logins.
+ *	EX_NOHOST -- The host specified did not exist.  This is used
+ *		in mail addresses or network requests.
+ *	EX_UNAVAILABLE -- A service is unavailable.  This can occur
+ *		if a support program or file does not exist.  This
+ *		can also be used as a catchall message when something
+ *		you wanted to do doesn't work, but you don't know
+ *		why.
+ *	EX_SOFTWARE -- An internal software error has been detected.
+ *		This should be limited to non-operating system related
+ *		errors as possible.
+ *	EX_OSERR -- An operating system error has been detected.
+ *		This is intended to be used for such things as "cannot
+ *		fork", "cannot create pipe", or the like.  It includes
+ *		things like getuid returning a user that does not
+ *		exist in the passwd file.
+ *	EX_OSFILE -- Some system file (e.g., /etc/passwd, /var/run/utmp,
+ *		etc.) does not exist, cannot be opened, or has some
+ *		sort of error (e.g., syntax error).
+ *	EX_CANTCREAT -- A (user specified) output file cannot be
+ *		created.
+ *	EX_IOERR -- An error occurred while doing I/O on some file.
+ *	EX_TEMPFAIL -- temporary failure, indicating something that
+ *		is not really an error.  In sendmail, this means
+ *		that a mailer (e.g.) could not create a connection,
+ *		and the request should be reattempted later.
+ *	EX_PROTOCOL -- the remote system returned something that
+ *		was "not possible" during a protocol exchange.
+ *	EX_NOPERM -- You did not have sufficient permission to
+ *		perform the operation.  This is not intended for
+ *		file system problems, which should use EX_NOINPUT or
+ *		EX_CANTCREAT, but rather for higher level permissions.
+ *	EX_CONFIG -- Something was found in an unconfigured or
+ *		misconfigured state.
+ */
+
+#define EX_OK		0	/* successful termination */
+
+#define EX__BASE	64	/* base value for error messages */
+
+#define EX_USAGE	64	/* command line usage error */
+#define EX_DATAERR	65	/* data format error */
+#define EX_NOINPUT	66	/* cannot open input */
+#define EX_NOUSER	67	/* addressee unknown */
+#define EX_NOHOST	68	/* host name unknown */
+#define EX_UNAVAILABLE	69	/* service unavailable */
+#define EX_SOFTWARE	70	/* internal software error */
+#define EX_OSERR	71	/* system error (e.g., can't fork) */
+#define EX_OSFILE	72	/* critical OS file missing */
+#define EX_CANTCREAT	73	/* can't create (user) output file */
+#define EX_IOERR	74	/* input/output error */
+#define EX_TEMPFAIL	75	/* temp failure; user is invited to retry */
+#define EX_PROTOCOL	76	/* remote error in protocol */
+#define EX_NOPERM	77	/* permission denied */
+#define EX_CONFIG	78	/* configuration error */
+
+#define EX__MAX		78	/* maximum listed value */
+
+#endif /* !_SYSEXITS_H_ */
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index a70abf5..ef454ab 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -158,6 +158,11 @@
   return 0;
 }
 
+int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+  return do_dl_iterate_phdr(cb, data);
+}
+
 void android_set_application_target_sdk_version(uint32_t target) {
   // lock to avoid modification in the middle of dlopen.
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b9a8f9d..c6e569a 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -393,7 +393,7 @@
 
 // Here, we only have to provide a callback to iterate across all the
 // loaded libraries. gcc_eh does the rest.
-int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
   int rv = 0;
   for (soinfo* si = solist; si != nullptr; si = si->next) {
     dl_phdr_info dl_info;
@@ -1159,7 +1159,7 @@
 
   ZipEntry entry;
 
-  if (FindEntry(handle, ZipEntryName(file_path), &entry) != 0) {
+  if (FindEntry(handle, ZipString(file_path), &entry) != 0) {
     // Entry was not found.
     close(fd);
     return -1;
diff --git a/linker/linker.h b/linker/linker.h
index 43b1e07..9bca7f3 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -428,6 +428,8 @@
 soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo);
 void do_dlclose(soinfo* si);
 
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
+
 const ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle);
 soinfo* find_containing_library(const void* addr);
 
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 1c01c62..92e3287 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -51,12 +51,12 @@
 
 TEST(dlfcn, dlsym_in_executable) {
   dlerror(); // Clear any pending errors.
-  void* self = dlopen(NULL, RTLD_NOW);
-  ASSERT_TRUE(self != NULL);
-  ASSERT_TRUE(dlerror() == NULL);
+  void* self = dlopen(nullptr, RTLD_NOW);
+  ASSERT_TRUE(self != nullptr);
+  ASSERT_TRUE(dlerror() == nullptr);
 
   void* sym = dlsym(self, "DlSymTestFunction");
-  ASSERT_TRUE(sym != NULL);
+  ASSERT_TRUE(sym != nullptr);
 
   void (*function)() = reinterpret_cast<void(*)()>(sym);
 
@@ -175,11 +175,11 @@
 
 TEST(dlfcn, dlopen_noload) {
   void* handle = dlopen("libtest_simple.so", RTLD_NOW | RTLD_NOLOAD);
-  ASSERT_TRUE(handle == NULL);
+  ASSERT_TRUE(handle == nullptr);
   handle = dlopen("libtest_simple.so", RTLD_NOW);
   void* handle2 = dlopen("libtest_simple.so", RTLD_NOW | RTLD_NOLOAD);
-  ASSERT_TRUE(handle != NULL);
-  ASSERT_TRUE(handle2 != NULL);
+  ASSERT_TRUE(handle != nullptr);
+  ASSERT_TRUE(handle2 != nullptr);
   ASSERT_TRUE(handle == handle2);
   ASSERT_EQ(0, dlclose(handle));
   ASSERT_EQ(0, dlclose(handle2));
@@ -220,11 +220,11 @@
   // first check the set case
   setenv("IFUNC_CHOICE", "set", 1);
   void* handle = dlopen("libtest_ifunc.so", RTLD_NOW);
-  ASSERT_TRUE(handle != NULL);
+  ASSERT_TRUE(handle != nullptr);
   fn_ptr foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo"));
   fn_ptr foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library"));
-  ASSERT_TRUE(foo_ptr != NULL);
-  ASSERT_TRUE(foo_library_ptr != NULL);
+  ASSERT_TRUE(foo_ptr != nullptr);
+  ASSERT_TRUE(foo_library_ptr != nullptr);
   ASSERT_EQ(strncmp("set", foo_ptr(), 3), 0);
   ASSERT_EQ(strncmp("set", foo_library_ptr(), 3), 0);
   dlclose(handle);
@@ -232,11 +232,11 @@
   // then check the unset case
   unsetenv("IFUNC_CHOICE");
   handle = dlopen("libtest_ifunc.so", RTLD_NOW);
-  ASSERT_TRUE(handle != NULL);
+  ASSERT_TRUE(handle != nullptr);
   foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo"));
   foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library"));
-  ASSERT_TRUE(foo_ptr != NULL);
-  ASSERT_TRUE(foo_library_ptr != NULL);
+  ASSERT_TRUE(foo_ptr != nullptr);
+  ASSERT_TRUE(foo_library_ptr != nullptr);
   ASSERT_EQ(strncmp("unset", foo_ptr(), 5), 0);
   ASSERT_EQ(strncmp("unset", foo_library_ptr(), 3), 0);
   dlclose(handle);
@@ -315,9 +315,9 @@
   typedef int (*fn_t) (void);
   fn_t fn, fn2;
   fn = reinterpret_cast<fn_t>(dlsym(RTLD_DEFAULT, "check_order_dlsym_get_answer"));
-  ASSERT_TRUE(fn != NULL) << dlerror();
+  ASSERT_TRUE(fn != nullptr) << dlerror();
   fn2 = reinterpret_cast<fn_t>(dlsym(RTLD_DEFAULT, "check_order_dlsym_get_answer2"));
-  ASSERT_TRUE(fn2 != NULL) << dlerror();
+  ASSERT_TRUE(fn2 != nullptr) << dlerror();
 
   ASSERT_EQ(42, fn());
   ASSERT_EQ(43, fn2());
@@ -718,7 +718,7 @@
 
 TEST(dlfcn, dlopen_failure) {
   void* self = dlopen("/does/not/exist", RTLD_NOW);
-  ASSERT_TRUE(self == NULL);
+  ASSERT_TRUE(self == nullptr);
 #if defined(__BIONIC__)
   ASSERT_STREQ("dlopen failed: library \"/does/not/exist\" not found", dlerror());
 #else
@@ -737,7 +737,7 @@
   ASSERT_SUBSTR("/main/thread", main_thread_error);
 
   pthread_t t;
-  ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentDlErrorFn, NULL));
+  ASSERT_EQ(0, pthread_create(&t, nullptr, ConcurrentDlErrorFn, nullptr));
   void* result;
   ASSERT_EQ(0, pthread_join(t, &result));
   char* child_thread_error = static_cast<char*>(result);
@@ -749,31 +749,31 @@
 
 TEST(dlfcn, dlsym_failures) {
   dlerror(); // Clear any pending errors.
-  void* self = dlopen(NULL, RTLD_NOW);
-  ASSERT_TRUE(self != NULL);
-  ASSERT_TRUE(dlerror() == NULL);
+  void* self = dlopen(nullptr, RTLD_NOW);
+  ASSERT_TRUE(self != nullptr);
+  ASSERT_TRUE(dlerror() == nullptr);
 
   void* sym;
 
 #if defined(__BIONIC__) && !defined(__LP64__)
   // RTLD_DEFAULT in lp32 bionic is not (void*)0
   // so it can be distinguished from the NULL handle.
-  sym = dlsym(NULL, "test");
-  ASSERT_TRUE(sym == NULL);
+  sym = dlsym(nullptr, "test");
+  ASSERT_TRUE(sym == nullptr);
   ASSERT_SUBSTR("dlsym library handle is null", dlerror());
 #endif
 
   // NULL symbol name.
 #if defined(__BIONIC__)
   // glibc marks this parameter non-null and SEGVs if you cheat.
-  sym = dlsym(self, NULL);
-  ASSERT_TRUE(sym == NULL);
+  sym = dlsym(self, nullptr);
+  ASSERT_TRUE(sym == nullptr);
   ASSERT_SUBSTR("", dlerror());
 #endif
 
   // Symbol that doesn't exist.
   sym = dlsym(self, "ThisSymbolDoesNotExist");
-  ASSERT_TRUE(sym == NULL);
+  ASSERT_TRUE(sym == nullptr);
   ASSERT_SUBSTR("undefined symbol: ThisSymbolDoesNotExist", dlerror());
 
   ASSERT_EQ(0, dlclose(self));
@@ -781,12 +781,12 @@
 
 TEST(dlfcn, dladdr_executable) {
   dlerror(); // Clear any pending errors.
-  void* self = dlopen(NULL, RTLD_NOW);
-  ASSERT_TRUE(self != NULL);
-  ASSERT_TRUE(dlerror() == NULL);
+  void* self = dlopen(nullptr, RTLD_NOW);
+  ASSERT_TRUE(self != nullptr);
+  ASSERT_TRUE(dlerror() == nullptr);
 
   void* sym = dlsym(self, "DlSymTestFunction");
-  ASSERT_TRUE(sym != NULL);
+  ASSERT_TRUE(sym != nullptr);
 
   // Deliberately ask dladdr for an address inside a symbol, rather than the symbol base address.
   void* addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(sym) + 2);
@@ -861,12 +861,12 @@
   dlerror(); // Clear any pending errors.
 
   // No symbol corresponding to NULL.
-  ASSERT_EQ(dladdr(NULL, &info), 0); // Zero on error, non-zero on success.
-  ASSERT_TRUE(dlerror() == NULL); // dladdr(3) doesn't set dlerror(3).
+  ASSERT_EQ(dladdr(nullptr, &info), 0); // Zero on error, non-zero on success.
+  ASSERT_TRUE(dlerror() == nullptr); // dladdr(3) doesn't set dlerror(3).
 
   // No symbol corresponding to a stack address.
   ASSERT_EQ(dladdr(&info, &info), 0); // Zero on error, non-zero on success.
-  ASSERT_TRUE(dlerror() == NULL); // dladdr(3) doesn't set dlerror(3).
+  ASSERT_TRUE(dlerror() == nullptr); // dladdr(3) doesn't set dlerror(3).
 }
 
 // GNU-style ELF hash tables are incompatible with the MIPS ABI.
@@ -922,49 +922,49 @@
 
 #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);
+  handle = dlopen(nullptr, 0);
+  ASSERT_TRUE(handle == nullptr);
   ASSERT_SUBSTR("invalid", dlerror());
 #endif
 
-  handle = dlopen(NULL, 0xffffffff);
-  ASSERT_TRUE(handle == NULL);
+  handle = dlopen(nullptr, 0xffffffff);
+  ASSERT_TRUE(handle == nullptr);
   ASSERT_SUBSTR("invalid", dlerror());
 
   // glibc actually allows you to choose both RTLD_NOW and RTLD_LAZY at the same time, and so do we.
-  handle = dlopen(NULL, RTLD_NOW|RTLD_LAZY);
-  ASSERT_TRUE(handle != NULL);
-  ASSERT_SUBSTR(NULL, dlerror());
+  handle = dlopen(nullptr, RTLD_NOW|RTLD_LAZY);
+  ASSERT_TRUE(handle != nullptr);
+  ASSERT_SUBSTR(nullptr, dlerror());
 }
 
 TEST(dlfcn, rtld_default_unknown_symbol) {
   void* addr = dlsym(RTLD_DEFAULT, "ANY_UNKNOWN_SYMBOL_NAME");
-  ASSERT_TRUE(addr == NULL);
+  ASSERT_TRUE(addr == nullptr);
 }
 
 TEST(dlfcn, rtld_default_known_symbol) {
   void* addr = dlsym(RTLD_DEFAULT, "fopen");
-  ASSERT_TRUE(addr != NULL);
+  ASSERT_TRUE(addr != nullptr);
 }
 
 TEST(dlfcn, rtld_next_unknown_symbol) {
   void* addr = dlsym(RTLD_NEXT, "ANY_UNKNOWN_SYMBOL_NAME");
-  ASSERT_TRUE(addr == NULL);
+  ASSERT_TRUE(addr == nullptr);
 }
 
 TEST(dlfcn, rtld_next_known_symbol) {
   void* addr = dlsym(RTLD_NEXT, "fopen");
-  ASSERT_TRUE(addr != NULL);
+  ASSERT_TRUE(addr != nullptr);
 }
 
 TEST(dlfcn, dlsym_weak_func) {
   dlerror();
   void* handle = dlopen("libtest_dlsym_weak_func.so", RTLD_NOW);
-  ASSERT_TRUE(handle != NULL);
+  ASSERT_TRUE(handle != nullptr);
 
   int (*weak_func)();
   weak_func = reinterpret_cast<int (*)()>(dlsym(handle, "weak_func"));
-  ASSERT_TRUE(weak_func != NULL) << "dlerror: " << dlerror();
+  ASSERT_TRUE(weak_func != nullptr) << "dlerror: " << dlerror();
   EXPECT_EQ(42, weak_func());
   dlclose(handle);
 }
@@ -982,8 +982,8 @@
 TEST(dlfcn, dlopen_symlink) {
   void* handle1 = dlopen("libdlext_test.so", RTLD_NOW);
   void* handle2 = dlopen("libdlext_test_v2.so", RTLD_NOW);
-  ASSERT_TRUE(handle1 != NULL);
-  ASSERT_TRUE(handle2 != NULL);
+  ASSERT_TRUE(handle1 != nullptr);
+  ASSERT_TRUE(handle2 != nullptr);
   ASSERT_EQ(handle1, handle2);
   dlclose(handle1);
   dlclose(handle2);