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 8f2f6d221c42b2e5b974848c600633c35fedfce9..75d315a9cc590edec5d072fee56a81a6ee367b05 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 d3e64c40d85dd72b71abbb756aae5205266cf01f..d59465c942d9cb1cc4b25cca83f0cb694c09648f 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 8b3b61b663e446b1159ad5d19328352b5e6f2381..885b53b60b05a55567118b8aa76efadde09b69a1 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 6b62c058837b33a9a80010601beaeeca4f2323bf..f78b87990fd30d476ead41a70b2ffbaa4caa570b 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 3cc244b7fd19381a89d99f8026bae4db42336497..d95c2d1156baf66190df7fa7538bd4d824a4c880 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.  */