fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / sunrpc / svc.c
index 6357d51..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
@@ -86,6 +87,8 @@ xprt_register (SVCXPRT *xprt)
 
   if (sock < _rpc_dtablesize ())
     {
+      struct pollfd *new_svc_pollfd;
+
       xports[sock] = xprt;
       if (sock < FD_SETSIZE)
        FD_SET (sock, &svc_fdset);
@@ -100,17 +103,20 @@ xprt_register (SVCXPRT *xprt)
            return;
          }
 
-      ++svc_max_pollfd;
-      svc_pollfd = realloc (svc_pollfd,
-                           sizeof (struct pollfd) * svc_max_pollfd);
-      if (svc_pollfd == NULL) /* Out of memory */
+      new_svc_pollfd = (struct pollfd *) realloc (svc_pollfd,
+                                                 sizeof (struct pollfd)
+                                                 * (svc_max_pollfd + 1));
+      if (new_svc_pollfd == NULL) /* Out of memory */
        return;
+      svc_pollfd = new_svc_pollfd;
+      ++svc_max_pollfd;
 
       svc_pollfd[svc_max_pollfd - 1].fd = sock;
       svc_pollfd[svc_max_pollfd - 1].events = (POLLIN | POLLPRI |
                                               POLLRDNORM | POLLRDBAND);
     }
 }
+libc_hidden_def (xprt_register)
 
 /* De-activate a transport handle. */
 void
@@ -131,6 +137,7 @@ xprt_unregister (SVCXPRT *xprt)
          svc_pollfd[i].fd = -1;
     }
 }
+libc_hidden_def (xprt_unregister)
 
 
 /* ********************** CALLOUT list related stuff ************* */
@@ -154,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. */
@@ -179,15 +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;
 }
+libc_hidden_def (svc_register)
 
 /* Remove a service program from the callout list. */
 void
@@ -207,8 +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);
 }
+libc_hidden_def (svc_unregister)
 
 /* ******************* REPLY GENERATION ROUTINES  ************ */
 
@@ -227,6 +254,7 @@ svc_sendreply (register SVCXPRT *xprt, xdrproc_t xdr_results,
   rply.acpted_rply.ar_results.proc = xdr_results;
   return SVC_REPLY (xprt, &rply);
 }
+INTDEF (svc_sendreply)
 
 /* No procedure error reply */
 void
@@ -253,6 +281,7 @@ svcerr_decode (register SVCXPRT *xprt)
   rply.acpted_rply.ar_stat = GARBAGE_ARGS;
   SVC_REPLY (xprt, &rply);
 }
+INTDEF (svcerr_decode)
 
 /* Some system error */
 void
@@ -279,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
@@ -299,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
@@ -315,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 ******************* */
 
@@ -341,47 +373,54 @@ svc_getreq (int rdfds)
 
   FD_ZERO (&readfds);
   readfds.fds_bits[0] = rdfds;
-  svc_getreqset (&readfds);
+  INTUSE(svc_getreqset) (&readfds);
 }
+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)))
-      svc_getreq_common (sock + 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)
 
 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
-           svc_getreq_common (p->fd);
+           INTUSE(svc_getreq_common) (p->fd);
+
+         if (++fds_found >= pollretval)
+           break;
        }
     }
 }
+INTDEF (svc_getreq_poll)
 
 
 void
@@ -427,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;
@@ -473,6 +512,7 @@ svc_getreq_common (const int fd)
     }
   while (stat == XPRT_MOREREQS);
 }
+INTDEF (svc_getreq_common)
 
 #ifdef _RPC_THREAD_SAFE_