about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2012-11-19 13:01:43 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2012-11-19 13:02:48 +0530
commitcfde9b463d63092ff0908d4c2748ace648e2ead8 (patch)
tree9ac0df733a6b3a01305f937e5e55ea63f3387328
parentf6da27e53695ad1cc0e2a9490358decbbfdff5e5 (diff)
downloadglibc-cfde9b463d63092ff0908d4c2748ace648e2ead8.tar.gz
glibc-cfde9b463d63092ff0908d4c2748ace648e2ead8.tar.xz
glibc-cfde9b463d63092ff0908d4c2748ace648e2ead8.zip
Return EAI_SYSTEM if we're out of file descriptors
Resolves BZ #14719.
-rw-r--r--ChangeLog11
-rw-r--r--NEWS4
-rw-r--r--nss/getXXbyYY_r.c7
-rw-r--r--resolv/nss_dns/dns-host.c25
-rw-r--r--sysdeps/posix/getaddrinfo.c6
5 files changed, 46 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f2f6d221c..75d315a9cc 100644
--- 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 d3e64c40d8..d59465c942 100644
--- 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.
 
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 8b3b61b663..885b53b60b 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -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
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 6b62c05883..f78b87990f 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -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;
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 3cc244b7fd..d95c2d1156 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -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.  */