Remove thread-local variable h_errno in gethostby{name, addr} related APIs

Using a thread-local variable to return an int to the caller is a hack and
adds a lot of complexity. Return error code with an int pointer instead.

Test: built, flashed, booted
      system/netd/tests/runtests.sh pass

Change-Id: Ie9da1a6b18525967f0e8fe3d54b0df18e37d2b0e
diff --git a/resolv/gethnamaddr.cpp b/resolv/gethnamaddr.cpp
index 0ccc3d7..fd56f26 100644
--- a/resolv/gethnamaddr.cpp
+++ b/resolv/gethnamaddr.cpp
@@ -140,12 +140,11 @@
 static int _dns_gethtbyname(const char* name, int af, getnamaddr* info);
 
 static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
-                                  size_t hbuflen, int* errorp,
-                                  const android_net_context* netcontext);
+                                  size_t hbuflen, const android_net_context* netcontext);
 static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
-                                       char* buf, size_t buflen, int* he);
+                                       char* buf, size_t buflen);
 static int android_gethostbyaddrfornetcontext_proxy_internal(const void*, socklen_t, int,
-                                                             struct hostent*, char*, size_t, int*,
+                                                             struct hostent*, char*, size_t,
                                                              const struct android_net_context*);
 static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
                                                     const struct android_net_context* netcontext,
@@ -471,9 +470,11 @@
 }
 
 static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
-                                       char* buf, size_t buflen, int* he) {
+                                       char* buf, size_t buflen) {
     getnamaddr info;
     size_t size;
+    // TODO: Remove it once the data member "he" of struct getnamaddr is removed.
+    int he = NETDB_INTERNAL;
 
     _DIAGASSERT(name != NULL);
 
@@ -485,7 +486,6 @@
             size = NS_IN6ADDRSZ;
             break;
         default:
-            *he = NETDB_INTERNAL;
             errno = EAFNOSUPPORT;
             return EAI_FAMILY;
     }
@@ -527,24 +527,20 @@
         }
     }
 
-    *he = NETDB_INTERNAL;
     info.hp = hp;
     info.buf = buf;
     info.buflen = buflen;
-    info.he = he;
-    if (!_hf_gethtbyname2(name, af, &info)) {
+    info.he = &he;  // TODO: Remove the data member "he" of struct getnamaddr.
+    if (_hf_gethtbyname2(name, af, &info)) {
         int error = _dns_gethtbyname(name, af, &info);
         if (error != 0) {
             return error;
         }
     }
-    *he = NETDB_SUCCESS;
     return 0;
 nospc:
-    *he = NETDB_INTERNAL;
     errno = ENOSPC;
-    // Bad arguments
-    return EAI_FAIL;
+    return EAI_MEMORY;
 fake:
     HENT_ARRAY(hp->h_addr_list, 1, buf, buflen);
     HENT_ARRAY(hp->h_aliases, 0, buf, buflen);
@@ -553,7 +549,6 @@
     if (size > buflen) goto nospc;
 
     if (inet_pton(af, name, buf) <= 0) {
-        *he = HOST_NOT_FOUND;
         return EAI_NODATA;
     }
     hp->h_addr_list[0] = buf;
@@ -562,32 +557,30 @@
     buflen -= size;
     HENT_SCOPY(hp->h_name, name, buf, buflen);
     if (res->options & RES_USE_INET6) map_v4v6_hostent(hp, &buf, buf + buflen);
-    *he = NETDB_SUCCESS;
     return 0;
 }
 
 // very similar in proxy-ness to android_getaddrinfo_proxy
 static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
-                                  size_t hbuflen, int* errorp,
-                                  const android_net_context* netcontext) {
+                                  size_t hbuflen, const android_net_context* netcontext) {
     res_setnetcontext(res, netcontext);
-    return gethostbyname_internal_real(name, af, res, hp, hbuf, hbuflen, errorp);
+    return gethostbyname_internal_real(name, af, res, hp, hbuf, hbuflen);
 }
 
 static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t len, int af,
                                                    struct hostent* hp, char* buf, size_t buflen,
-                                                   int* he,
                                                    const struct android_net_context* netcontext) {
     const u_char* uaddr = (const u_char*) addr;
     socklen_t size;
     struct getnamaddr info;
+    // TODO: Remove it once the data member "he" of struct getnamaddr is removed.
+    int he = NETDB_INTERNAL;
 
     _DIAGASSERT(addr != NULL);
 
     if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
         (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr*) addr) ||
          IN6_IS_ADDR_SITELOCAL((const struct in6_addr*) addr))) {
-        *he = HOST_NOT_FOUND;
         return EAI_NODATA;
     }
     if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
@@ -608,35 +601,30 @@
             break;
         default:
             errno = EAFNOSUPPORT;
-            *he = NETDB_INTERNAL;
             return EAI_FAMILY;
     }
     if (size != len) {
         errno = EINVAL;
-        *he = NETDB_INTERNAL;
         // TODO: Consider to remap error code without relying on errno.
         return EAI_SYSTEM;
     }
     info.hp = hp;
     info.buf = buf;
     info.buflen = buflen;
-    info.he = he;
-    *he = NETDB_INTERNAL;
-    if (!_hf_gethtbyaddr(uaddr, len, af, &info)) {
+    info.he = &he;  // TODO: Remove the data member "he" of struct getnamaddr.
+    if (_hf_gethtbyaddr(uaddr, len, af, &info)) {
         int error = _dns_gethtbyaddr(uaddr, len, af, netcontext, &info);
         if (error != 0) {
             return error;
         }
     }
-    *he = NETDB_SUCCESS;
     return 0;
 }
 
 static int android_gethostbyaddrfornetcontext_proxy_internal(
         const void* addr, socklen_t len, int af, struct hostent* hp, char* hbuf, size_t hbuflen,
-        int* he, const struct android_net_context* netcontext) {
-    return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, he,
-                                                   netcontext);
+        const struct android_net_context* netcontext) {
+    return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, netcontext);
 }
 
 struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, size_t buflen,
@@ -878,7 +866,8 @@
     }
 
     int ai_error = EAI_NODATA;
-    n = res_nsearch(res, name, C_IN, type, buf->buf, (int) sizeof(buf->buf), &ai_error);
+    int herrno = NETDB_INTERNAL;
+    n = res_nsearch(res, name, C_IN, type, buf->buf, (int) sizeof(buf->buf), &ai_error, &herrno);
     if (n < 0) {
         free(buf);
         debugprintf("res_nsearch failed (%d)\n", res, n);
@@ -887,14 +876,14 @@
         // get the nulltpr hp.
         // TODO: Adjust the error closed to res_nsend instead of here after h_errno is removed.
         if (ai_error == 0) {
-            return herrnoToAiError(h_errno);
+            return herrnoToAiError(herrno);
         }
         return ai_error;
     }
-    hp = getanswer(buf, n, name, type, res, info->hp, info->buf, info->buflen, info->he);
+    hp = getanswer(buf, n, name, type, res, info->hp, info->buf, info->buflen, &herrno);
     free(buf);
     if (hp == NULL) {
-        return herrnoToAiError(h_errno);
+        return herrnoToAiError(herrno);
     }
     return 0;
 }
@@ -952,7 +941,8 @@
     }
     res_setnetcontext(res, netcontext);
     int ai_error = 0;
-    n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int) sizeof(buf->buf), &ai_error);
+    int herrno = NETDB_INTERNAL;
+    n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int) sizeof(buf->buf), &ai_error, &herrno);
     if (n < 0) {
         free(buf);
         debugprintf("res_nquery failed (%d)\n", res, n);
@@ -963,12 +953,12 @@
         // query progress. DNS server may respond a DNS packet without any answer for queried
         // address. In this case, return error code from h_errno NO_DATA rather than rcode NOERROR
         // (ai_error).
-        return herrnoToAiError(h_errno);
+        return herrnoToAiError(herrno);
     }
-    hp = getanswer(buf, n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, info->he);
+    hp = getanswer(buf, n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, &herrno);
     free(buf);
     if (hp == NULL) {
-        return herrnoToAiError(h_errno);
+        return herrnoToAiError(herrno);
     }
 
     char* bf = (char*) (hp->h_addr_list + 2);
@@ -1011,7 +1001,7 @@
     if (res == NULL) return EAI_MEMORY;
     res_static* rs = res_get_static();  // For thread-safety.
     error = gethostbyname_internal(name, af, res, &rs->host, rs->hostbuf, sizeof(rs->hostbuf),
-                                   &h_errno, netcontext);
+                                   netcontext);
     if (error == 0) {
         *hp = &rs->host;
     }
@@ -1028,7 +1018,7 @@
                                                     hostent** hp) {
     struct res_static* rs = res_get_static();  // For thread-safety.
     int error = android_gethostbyaddrfornetcontext_proxy_internal(
-            addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), &h_errno, netcontext);
+            addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), netcontext);
     if (error == 0) *hp = &rs->host;
     return error;
 }