fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / sunrpc / svc.c
index 4e83959..60f6fcd 100644 (file)
@@ -61,6 +61,7 @@ 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 RPC_THREAD_VARIABLE(svc_head_s)
@@ -160,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. */
@@ -185,12 +197,18 @@ 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;
 }
@@ -214,7 +232,8 @@ 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);
 }
 libc_hidden_def (svc_unregister)
 
@@ -372,7 +391,7 @@ svc_getreqset (fd_set *readfds)
     setsize = FD_SETSIZE;
   maskp = readfds->fds_bits;
   for (sock = 0; sock < setsize; sock += NFDBITS)
-    for (mask = *maskp++; (bit = ffsl (mask)); mask ^= (1 << (bit - 1)))
+    for (mask = *maskp++; (bit = ffsl (mask)); mask ^= (1L << (bit - 1)))
       INTUSE(svc_getreq_common) (sock + bit - 1);
 }
 INTDEF (svc_getreqset)
@@ -380,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;
        }
     }
 }