Move xdr_* functions from nis/nis_xdr.h.
[kopensolaris-gnu/glibc.git] / nss / getXXbyYY_r.c
index d20fa34..2e5cc81 100644 (file)
@@ -56,6 +56,9 @@
 # define NSCD_NAME ADD_NSCD (REENTRANT_NAME)
 # define ADD_NSCD(name) ADD_NSCD1 (name)
 # define ADD_NSCD1(name) __nscd_##name
+# define NOT_USENSCD_NAME ADD_NOT_NSCDUSE (DATABASE_NAME)
+# define ADD_NOT_NSCDUSE(name) ADD_NOT_NSCDUSE1 (name)
+# define ADD_NOT_NSCDUSE1(name) __nss_not_use_nscd_##name
 #endif
 
 #define FUNCTION_NAME_STRING STRINGIZE (FUNCTION_NAME)
@@ -88,6 +91,8 @@ extern struct __res_state _res;
 /* The lookup function for the first entry of this service.  */
 extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp);
 
+/* Interval in which we transfer retry to contact the NSCD.  */
+#define NSS_NSCD_RETRY 100
 
 
 int
@@ -111,11 +116,18 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
 #endif
 
 #ifdef USE_NSCD
-  nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen H_ERRNO_VAR);
-  if (nscd_status < 1)
+  if (NOT_USENSCD_NAME && ++NOT_USENSCD_NAME > NSS_NSCD_RETRY)
+    NOT_USENSCD_NAME = 0;
+
+  if (!NOT_USENSCD_NAME)
     {
-      *result = nscd_status == 0 ? resbuf : NULL;
-      return nscd_status;
+      nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen
+                              H_ERRNO_VAR);
+      if (nscd_status < 1)
+       {
+         *result = nscd_status == 0 ? resbuf : NULL;
+         return nscd_status;
+       }
     }
 #endif
 
@@ -150,7 +162,19 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
   while (no_more == 0)
     {
       status = (*fct) (ADD_VARIABLES, resbuf, buffer, buflen,
-                      __errno_location () H_ERRNO_VAR);
+                      &errno H_ERRNO_VAR);
+
+      /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
+        provided buffer is too small.  In this case we should give
+        the user the possibility to enlarge the buffer and we should
+        not simply go on with the next service (even if the TRYAGAIN
+        action tells us so).  */
+      if (status == NSS_STATUS_TRYAGAIN
+#ifdef NEED_H_ERRNO
+         && *h_errnop == NETDB_INTERNAL
+#endif
+         && errno == ERANGE)
+       break;
 
       no_more = __nss_next (&nip, REENTRANT_NAME_STRING,
                            (void **) &fct, status, 0);