fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / sunrpc / svc.c
index 932813b..60f6fcd 100644 (file)
@@ -44,7 +44,7 @@
 #include <sys/poll.h>
 
 #ifdef _RPC_THREAD_SAFE_
-#define xports ((SVCXPRT **)RPC_THREAD_VARIABLE(svc_xports_s))
+#define xports RPC_THREAD_VARIABLE(svc_xports_s)
 #else
 static SVCXPRT **xports;
 #endif
@@ -61,9 +61,10 @@ struct svc_callout {
   rpcprog_t sc_prog;
   rpcvers_t sc_vers;
   void (*sc_dispatch) (struct svc_req *, SVCXPRT *);
+  bool_t sc_mapped;
 };
 #ifdef _RPC_THREAD_SAFE_
-#define svc_head ((struct svc_callout *)RPC_THREAD_VARIABLE(svc_head_s))
+#define svc_head RPC_THREAD_VARIABLE(svc_head_s)
 #else
 static struct svc_callout *svc_head;
 #endif
@@ -115,6 +116,7 @@ xprt_register (SVCXPRT *xprt)
                                               POLLRDNORM | POLLRDBAND);
     }
 }
+libc_hidden_def (xprt_register)
 
 /* De-activate a transport handle. */
 void
@@ -135,6 +137,7 @@ xprt_unregister (SVCXPRT *xprt)
          svc_pollfd[i].fd = -1;
     }
 }
+libc_hidden_def (xprt_unregister)
 
 
 /* ********************** CALLOUT list related stuff ************* */
@@ -158,6 +161,17 @@ done:
   return s;
 }
 
+
+static bool_t
+svc_is_mapped (rpcprog_t prog, rpcvers_t vers)
+{
+  struct svc_callout *prev;
+  register struct svc_callout *s;
+  s = svc_find (prog, vers, &prev);
+  return s!= NULL_SVC && s->sc_mapped;
+}
+
+
 /* Add a service program to the callout list.
    The dispatch routine will be called when a rpc request for this
    program number comes in. */
@@ -183,16 +197,22 @@ svc_register (SVCXPRT * xprt, rpcprog_t prog, rpcvers_t vers,
   s->sc_vers = vers;
   s->sc_dispatch = dispatch;
   s->sc_next = svc_head;
+  s->sc_mapped = FALSE;
   svc_head = s;
 
 pmap_it:
   /* now register the information with the local binder service */
   if (protocol)
-    return pmap_set (prog, vers, protocol, xprt->xp_port);
+    {
+      if (! pmap_set (prog, vers, protocol, xprt->xp_port))
+       return FALSE;
+
+      s->sc_mapped = TRUE;
+    }
 
   return TRUE;
 }
-INTDEF (svc_register)
+libc_hidden_def (svc_register)
 
 /* Remove a service program from the callout list. */
 void
@@ -212,9 +232,10 @@ svc_unregister (rpcprog_t prog, rpcvers_t vers)
   s->sc_next = NULL_SVC;
   mem_free ((char *) s, (u_int) sizeof (struct svc_callout));
   /* now unregister the information with the local binder service */
-  pmap_unset (prog, vers);
+  if (! svc_is_mapped (prog, vers))
+    pmap_unset (prog, vers);
 }
-INTDEF (svc_unregister)
+libc_hidden_def (svc_unregister)
 
 /* ******************* REPLY GENERATION ROUTINES  ************ */
 
@@ -287,6 +308,7 @@ svcerr_auth (SVCXPRT *xprt, enum auth_stat why)
   rply.rjcted_rply.rj_why = why;
   SVC_REPLY (xprt, &rply);
 }
+libc_hidden_def (svcerr_auth)
 
 /* Auth too weak error reply */
 void
@@ -307,6 +329,7 @@ svcerr_noprog (register SVCXPRT *xprt)
   rply.acpted_rply.ar_stat = PROG_UNAVAIL;
   SVC_REPLY (xprt, &rply);
 }
+libc_hidden_def (svcerr_noprog)
 
 /* Program version mismatch error reply */
 void
@@ -323,6 +346,7 @@ svcerr_progvers (register SVCXPRT *xprt, rpcvers_t low_vers,
   rply.acpted_rply.ar_vers.high = high_vers;
   SVC_REPLY (xprt, &rply);
 }
+libc_hidden_def (svcerr_progvers)
 
 /* ******************* SERVER INPUT STUFF ******************* */
 
@@ -356,16 +380,18 @@ INTDEF (svc_getreq)
 void
 svc_getreqset (fd_set *readfds)
 {
-  register u_int32_t mask;
-  register u_int32_t *maskp;
+  register fd_mask mask;
+  register fd_mask *maskp;
   register int setsize;
   register int sock;
   register int bit;
 
   setsize = _rpc_dtablesize ();
-  maskp = (u_int32_t *) readfds->fds_bits;
-  for (sock = 0; sock < setsize; sock += 32)
-    for (mask = *maskp++; (bit = ffs (mask)); mask ^= (1 << (bit - 1)))
+  if (setsize > FD_SETSIZE)
+    setsize = FD_SETSIZE;
+  maskp = readfds->fds_bits;
+  for (sock = 0; sock < setsize; sock += NFDBITS)
+    for (mask = *maskp++; (bit = ffsl (mask)); mask ^= (1L << (bit - 1)))
       INTUSE(svc_getreq_common) (sock + bit - 1);
 }
 INTDEF (svc_getreqset)
@@ -373,22 +399,24 @@ INTDEF (svc_getreqset)
 void
 svc_getreq_poll (struct pollfd *pfdp, int pollretval)
 {
-  register int i;
-  register int fds_found;
+  if (pollretval == 0)
+    return;
 
-  for (i = fds_found = 0; i < svc_max_pollfd && fds_found < pollretval; ++i)
+  register int fds_found;
+  for (int i = fds_found = 0; i < svc_max_pollfd; ++i)
     {
       register struct pollfd *p = &pfdp[i];
 
       if (p->fd != -1 && p->revents)
        {
          /* fd has input waiting */
-         ++fds_found;
-
          if (p->revents & POLLNVAL)
            xprt_unregister (xports[p->fd]);
          else
            INTUSE(svc_getreq_common) (p->fd);
+
+         if (++fds_found >= pollretval)
+           break;
        }
     }
 }
@@ -438,7 +466,7 @@ svc_getreq_common (const int fd)
              r.rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
              r.rq_xprt->xp_verf.oa_length = 0;
            }
-         else if ((why = _authenticate (&r, &msg)) != AUTH_OK)
+         else if ((why = INTUSE(_authenticate) (&r, &msg)) != AUTH_OK)
            {
              svcerr_auth (xprt, why);
              goto call_done;