Return EAI_SYSTEM if we're out of file descriptors
authorSiddhesh Poyarekar <siddhesh@redhat.com>
Mon, 19 Nov 2012 07:31:43 +0000 (13:01 +0530)
committerSiddhesh Poyarekar <siddhesh@redhat.com>
Mon, 19 Nov 2012 07:32:48 +0000 (13:02 +0530)
Resolves BZ #14719.

ChangeLog
NEWS
nss/getXXbyYY_r.c
resolv/nss_dns/dns-host.c
sysdeps/posix/getaddrinfo.c

index 8f2f6d2..75d315a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-11-19  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+       [BZ #14719]
+       * nss/getXXbyYY_r.c (INTERNAL (REENTRANT_NAME)): Set h_errno to
+       NETDB_INTERNAL when NSS_STATUS_UNAVAIL.
+       * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname3_r): Set
+       h_errno to NETDB_INTERNAL when errno is EMFILE or ENFILE.
+       (_nss_dns_gethostbyname4_r): Likewise.
+       * sysdeps/posix/getaddrinfo.c (gaih_inet): Set result to
+       EAI_SYSTEM if NSS_STATUS_UNAVAIL.
+
 2012-11-19  Peng Haitao  <penght@cn.fujitsu.com>
 
        [BZ #13763]
diff --git a/NEWS b/NEWS
index d3e64c4..d59465c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,8 +19,8 @@ Version 2.17
   14518, 14519, 14530, 14532, 14538, 14543, 14544, 14545, 14557, 14562,
   14568, 14576, 14579, 14583, 14587, 14595, 14602, 14610, 14621, 14638,
   14645, 14648, 14652, 14660, 14661, 14669, 14672, 14683, 14694, 14716,
-  14743, 14767, 14783, 14784, 14785, 14793, 14796, 14797, 14801, 14805,
-  14807, 14809, 14811, 14815, 14821, 14824, 14828, 14831, 14838.
+  14719, 14743, 14767, 14783, 14784, 14785, 14793, 14796, 14797, 14801,
+  14805, 14807, 14809, 14811, 14815, 14821, 14824, 14828, 14831, 14838.
 
 * Port to ARM AArch64 contributed by Linaro.
 
index 8b3b61b..885b53b 100644 (file)
@@ -284,7 +284,12 @@ done:
 #endif
   *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
 #ifdef NEED_H_ERRNO
-  if (status != NSS_STATUS_SUCCESS && ! any_service)
+  if (status == NSS_STATUS_UNAVAIL)
+    /* Either we failed to lookup the functions or the functions themselves
+       had a system error.  Set NETDB_INTERNAL here to let the caller know
+       that the errno may have the real reason for failure.  */
+      *h_errnop = NETDB_INTERNAL;
+  else if (status != NSS_STATUS_SUCCESS && !any_service)
     /* We were not able to use any service.  */
     *h_errnop = NO_RECOVERY;
 #endif
index 6b62c05..f78b879 100644 (file)
@@ -199,6 +199,11 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
          status = NSS_STATUS_TRYAGAIN;
          h_errno = TRY_AGAIN;
          break;
+       /* System has run out of file descriptors.  */
+       case EMFILE:
+       case ENFILE:
+         h_errno = NETDB_INTERNAL;
+         /* Fall through.  */
        case ECONNREFUSED:
        case ETIMEDOUT:
          status = NSS_STATUS_UNAVAIL;
@@ -311,14 +316,26 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
                              &ans2p, &nans2p, &resplen2);
   if (n < 0)
     {
-      if (errno == ESRCH)
+      switch (errno)
        {
+       case ESRCH:
          status = NSS_STATUS_TRYAGAIN;
          h_errno = TRY_AGAIN;
+         break;
+       /* System has run out of file descriptors.  */
+       case EMFILE:
+       case ENFILE:
+         h_errno = NETDB_INTERNAL;
+         /* Fall through.  */
+       case ECONNREFUSED:
+       case ETIMEDOUT:
+         status = NSS_STATUS_UNAVAIL;
+         break;
+       default:
+         status = NSS_STATUS_NOTFOUND;
+         break;
        }
-      else
-       status = (errno == ECONNREFUSED
-                 ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND);
+
       *herrnop = h_errno;
       if (h_errno == TRY_AGAIN)
        *errnop = EAGAIN;
index 3cc244b..d95c2d1 100644 (file)
@@ -1049,6 +1049,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
          _res.options |= old_res_options & RES_USE_INET6;
 
+         if (status == NSS_STATUS_UNAVAIL)
+           {
+             result = GAIH_OKIFUNSPEC | -EAI_SYSTEM;
+             goto free_and_return;
+           }
+
          if (no_data != 0 && no_inet6_data != 0)
            {
              /* If both requests timed out report this.  */