Reimplement popen(3)/pclose(3).

pclose(3) is now an alias for fclose(3). We could add a FORTIFY check
that you use pclose(3) if and only if you used popen(3), but there seems
little value to that when we can just do the right thing.

This patch also adds the missing locking to _fwalk --- we need to lock
both the global list of FILE*s and also each FILE* we touch. POSIX says
that "The popen() function shall ensure that any streams from previous
popen() calls that remain open in the parent process are closed in the
new child process", which we implement via _fwalk(fclose) in the child,
but we might want to just make *all* popen(3) file descriptors O_CLOEXEC
in all cases.

Ignore fewer errors in popen(3) failure cases.

Improve popen(3) test coverage.

Bug: http://b/72470344
Test: ran tests
Change-Id: Ic937594bf28ec88b375f7e5825b9c05f500af438
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index c817b63..a26bee4 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -29,18 +29,23 @@
  *
  */
 
-#include <sys/types.h>
-#include <sys/mman.h>
+#include "atexit.h"
+
+#include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include "atexit.h"
-#include "private/thread_private.h"
+#include <sys/mman.h>
+#include <sys/types.h>
 
 /* BEGIN android-changed */
 #include "private/bionic_prctl.h"
 /* END android-changed */
 
+static pthread_mutex_t g_atexit_lock = PTHREAD_MUTEX_INITIALIZER;
+#define _ATEXIT_LOCK() pthread_mutex_lock(&g_atexit_lock)
+#define _ATEXIT_UNLOCK() pthread_mutex_unlock(&g_atexit_lock)
+
 struct atexit {
 	struct atexit *next;		/* next in list */
 	int ind;			/* next index in this table */
@@ -79,15 +84,14 @@
 int
 __cxa_atexit(void (*func)(void *), void *arg, void *dso)
 {
-	struct atexit *p = __atexit;
 	struct atexit_fn *fnp;
 	size_t pgsize = getpagesize();
 	int ret = -1;
 
-	if (pgsize < sizeof(*p))
+	if (pgsize < sizeof(struct atexit))
 		return (-1);
 	_ATEXIT_LOCK();
-	p = __atexit;
+	struct atexit *p = __atexit;
 	if (p != NULL) {
 		if (p->ind + 1 >= p->max)
 			p = NULL;
@@ -185,8 +189,7 @@
 	}
 	_ATEXIT_UNLOCK();
 
-  extern void __libc_stdio_cleanup(void);
-  __libc_stdio_cleanup();
+  fflush(NULL);
 
   /* BEGIN android-changed: call __unregister_atfork if dso is not null */
   if (dso != NULL) {