Revert "Revert "More pthreads cleanup.""

This reverts commit 6f94de3ca49e4ea147b1c59e5818fa175846518f

(Doesn't try to increase the number of TLS slots; that leads to
an inability to boot. Adds more tests.)

Change-Id: Ia7d25ba3995219ed6e686463dbba80c95cc831ca
diff --git a/libc/bionic/stubs.cpp b/libc/bionic/stubs.cpp
index 3f24d1b..8ddc326 100644
--- a/libc/bionic/stubs.cpp
+++ b/libc/bionic/stubs.cpp
@@ -31,15 +31,17 @@
 #include <grp.h>
 #include <mntent.h>
 #include <netdb.h>
-#include <private/android_filesystem_config.h>
-#include <private/debug_format.h>
-#include <private/logd.h>
 #include <pthread.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "private/android_filesystem_config.h"
+#include "private/debug_format.h"
+#include "private/ErrnoRestorer.h"
+#include "private/logd.h"
+
 // Thread-specific state for the non-reentrant functions.
 static pthread_once_t stubs_once = PTHREAD_ONCE_INIT;
 static pthread_key_t stubs_key;
@@ -58,7 +60,7 @@
                       passwd** result) {
   // getpwnam_r and getpwuid_r don't modify errno, but library calls we
   // make might.
-  int old_errno = errno;
+  ErrnoRestorer errno_restorer;
   *result = NULL;
 
   // Our implementation of getpwnam(3) and getpwuid(3) use thread-local
@@ -69,9 +71,7 @@
   // POSIX allows failure to find a match to be considered a non-error.
   // Reporting success (0) but with *result NULL is glibc's behavior.
   if (src == NULL) {
-    int rc = (errno == ENOENT) ? 0 : errno;
-    errno = old_errno;
-    return rc;
+    return (errno == ENOENT) ? 0 : errno;
   }
 
   // Work out where our strings will go in 'buf', and whether we've got
@@ -84,13 +84,11 @@
   dst->pw_shell = buf + required_byte_count;
   required_byte_count += strlen(src->pw_shell) + 1;
   if (byte_count < required_byte_count) {
-    errno = old_errno;
     return ERANGE;
   }
 
   // Copy the strings.
-  snprintf(buf, byte_count, "%s%c%s%c%s",
-           src->pw_name, 0, src->pw_dir, 0, src->pw_shell);
+  snprintf(buf, byte_count, "%s%c%s%c%s", src->pw_name, 0, src->pw_dir, 0, src->pw_shell);
 
   // pw_passwd is non-POSIX and unused (always NULL) in bionic.
   // pw_gecos is non-POSIX and missing in bionic.
@@ -101,7 +99,6 @@
   dst->pw_uid = src->pw_uid;
 
   *result = dst;
-  errno = old_errno;
   return 0;
 }