fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / sunrpc / svc_tcp.c
index 0c2ce96..539a2b8 100644 (file)
@@ -44,14 +44,16 @@ static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
+#include <libintl.h>
 #include <rpc/rpc.h>
 #include <sys/socket.h>
+#include <sys/poll.h>
 #include <errno.h>
 #include <stdlib.h>
 
 #ifdef USE_IN_LIBIO
+# include <wchar.h>
 # include <libio/iolibio.h>
-# define fputs(s, f) _IO_fputs (s, f)
 #endif
 
 /*
@@ -79,14 +81,23 @@ static const struct xp_ops svctcp_op =
  */
 static bool_t rendezvous_request (SVCXPRT *, struct rpc_msg *);
 static enum xprt_stat rendezvous_stat (SVCXPRT *);
+static void svctcp_rendezvous_abort (void) __attribute__ ((__noreturn__));
+
+/* This function makes sure abort() relocation goes through PLT
+   and thus can be lazy bound.  */
+static void
+svctcp_rendezvous_abort (void)
+{
+  abort ();
+};
 
 static const struct xp_ops svctcp_rendezvous_op =
 {
   rendezvous_request,
   rendezvous_stat,
-  (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) abort,
-  (bool_t (*) (SVCXPRT *, struct rpc_msg *)) abort,
-  (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) abort,
+  (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) svctcp_rendezvous_abort,
+  (bool_t (*) (SVCXPRT *, struct rpc_msg *)) svctcp_rendezvous_abort,
+  (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) svctcp_rendezvous_abort,
   svctcp_destroy
 };
 
@@ -151,10 +162,10 @@ svctcp_create (int sock, u_int sendsize, u_int recvsize)
   if (bindresvport (sock, &addr))
     {
       addr.sin_port = 0;
-      (void) bind (sock, (struct sockaddr *) &addr, len);
+      (void) __bind (sock, (struct sockaddr *) &addr, len);
     }
-  if ((getsockname (sock, (struct sockaddr *) &addr, &len) != 0) ||
-      (listen (sock, 2) != 0))
+  if ((__getsockname (sock, (struct sockaddr *) &addr, &len) != 0) ||
+      (__listen (sock, SOMAXCONN) != 0))
     {
       perror (_("svc_tcp.c - cannot getsockname or listen"));
       if (madesock)
@@ -162,19 +173,16 @@ svctcp_create (int sock, u_int sendsize, u_int recvsize)
       return (SVCXPRT *) NULL;
     }
   r = (struct tcp_rendezvous *) mem_alloc (sizeof (*r));
-  if (r == NULL)
+  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
+  if (r == NULL || xprt == NULL)
     {
-      (void) fputs (_("svctcp_create: out of memory\n"), stderr);
+      (void) __fxprintf (NULL, "%s", _("svctcp_create: out of memory\n"));
+      mem_free (r, sizeof (*r));
+      mem_free (xprt, sizeof (SVCXPRT));
       return NULL;
     }
   r->sendsize = sendsize;
   r->recvsize = recvsize;
-  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
-  if (xprt == NULL)
-    {
-      (void) fputs (_("svctcp_create: out of memory\n"), stderr);
-      return NULL;
-    }
   xprt->xp_p2 = NULL;
   xprt->xp_p1 = (caddr_t) r;
   xprt->xp_verf = _null_auth;
@@ -203,22 +211,18 @@ makefd_xprt (int fd, u_int sendsize, u_int recvsize)
   struct tcp_conn *cd;
 
   xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
-  if (xprt == (SVCXPRT *) NULL)
-    {
-      (void) fputs (_("svc_tcp: makefd_xprt: out of memory\n"), stderr);
-      goto done;
-    }
   cd = (struct tcp_conn *) mem_alloc (sizeof (struct tcp_conn));
-  if (cd == (struct tcp_conn *) NULL)
+  if (xprt == (SVCXPRT *) NULL || cd == NULL)
     {
-      (void) fputs (_("svc_tcp: makefd_xprt: out of memory\n"), stderr);
-      mem_free ((char *) xprt, sizeof (SVCXPRT));
-      xprt = (SVCXPRT *) NULL;
-      goto done;
+      (void) __fxprintf (NULL, "%s",
+                        _("svc_tcp: makefd_xprt: out of memory\n"));
+      mem_free (xprt, sizeof (SVCXPRT));
+      mem_free (cd, sizeof (struct tcp_conn));
+      return NULL;
     }
   cd->strm_stat = XPRT_IDLE;
-  xdrrec_create (&(cd->xdrs), sendsize, recvsize,
-                (caddr_t) xprt, readtcp, writetcp);
+  INTUSE(xdrrec_create) (&(cd->xdrs), sendsize, recvsize,
+                        (caddr_t) xprt, readtcp, writetcp);
   xprt->xp_p2 = NULL;
   xprt->xp_p1 = (caddr_t) cd;
   xprt->xp_verf.oa_base = cd->verf_body;
@@ -227,7 +231,6 @@ makefd_xprt (int fd, u_int sendsize, u_int recvsize)
   xprt->xp_port = 0;           /* this is a connection, not a rendezvouser */
   xprt->xp_sock = fd;
   xprt_register (xprt);
-done:
   return xprt;
 }
 
@@ -252,7 +255,7 @@ again:
    * make a new transporter (re-uses xprt)
    */
   xprt = makefd_xprt (sock, r->sendsize, r->recvsize);
-  xprt->xp_raddr = addr;
+  memcpy (&xprt->xp_raddr, &addr, sizeof (addr));
   xprt->xp_addrlen = len;
   return FALSE;                /* there is never an rpc msg to be processed */
 }
@@ -284,66 +287,45 @@ svctcp_destroy (SVCXPRT *xprt)
   mem_free ((caddr_t) xprt, sizeof (SVCXPRT));
 }
 
-/*
- * All read operations timeout after 35 seconds.
- * A timeout is fatal for the connection.
- */
-static struct timeval wait_per_try = {35, 0};
 
 /*
  * reads data from the tcp connection.
  * any error is fatal and the connection is closed.
  * (And a read of zero bytes is a half closed stream => error.)
- *
- * Note: we have to be careful here not to allow ourselves to become
- * blocked too long in this routine.  While we're waiting for data from one
- * client, another client may be trying to connect.  To avoid this situation,
- * some code from svc_run() is transplanted here: the select() loop checks
- * all RPC descriptors including the one we want and calls svc_getreqset2()
- * to handle new requests if any are detected.
  */
 static int
 readtcp (char *xprtptr, char *buf, int len)
 {
   SVCXPRT *xprt = (SVCXPRT *)xprtptr;
   int sock = xprt->xp_sock;
-#ifdef FD_SETSIZE
-  fd_set readfds;
-#else
-  int mask = 1 << sock;
-  int readfds;
-#endif /* def FD_SETSIZE */
-  while (1)
+  int milliseconds = 35 * 1000;
+  struct pollfd pollfd;
+
+  do
     {
-      struct timeval timeout = wait_per_try;
-      readfds = svc_fdset;
-#ifdef FD_SETSIZE
-      FD_SET (sock, &readfds);
-#else
-      readfds |= (1 << sock);
-#endif /* def FD_SETSIZE */
-      if (__select (_rpc_dtablesize (), &readfds, (fd_set *) NULL,
-                   (fd_set *) NULL, &timeout) <= 0)
+      pollfd.fd = sock;
+      pollfd.events = POLLIN;
+      switch (__poll (&pollfd, 1, milliseconds))
        {
+       case -1:
          if (errno == EINTR)
            continue;
+         /*FALLTHROUGH*/
+       case 0:
          goto fatal_err;
+       default:
+          if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
+              || (pollfd.revents & POLLNVAL))
+            goto fatal_err;
+         break;
        }
-
-#ifdef FD_SETSIZE
-      if (FD_ISSET (sock, &readfds))
-#else
-      if (readfds == mask)
-#endif /* def FD_SETSIZE */
-       break;
-
-      svc_getreqset (&readfds);
     }
+  while ((pollfd.revents & POLLIN) == 0);
 
   if ((len = __read (sock, buf, len)) > 0)
     return len;
 
-fatal_err:
+ fatal_err:
   ((struct tcp_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
   return -1;
 }
@@ -362,12 +344,11 @@ writetcp (char *xprtptr, char * buf, int len)
     {
       if ((i = __write (xprt->xp_sock, buf, cnt)) < 0)
        {
-         ((struct tcp_conn *) (xprt->xp_p1))->strm_stat =
-           XPRT_DIED;
-         return (-1);
+         ((struct tcp_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
+         return -1;
        }
     }
-  return (len);
+  return len;
 }
 
 static enum xprt_stat
@@ -377,68 +358,55 @@ svctcp_stat (SVCXPRT *xprt)
   (struct tcp_conn *) (xprt->xp_p1);
 
   if (cd->strm_stat == XPRT_DIED)
-    return (XPRT_DIED);
-  if (!xdrrec_eof (&(cd->xdrs)))
-    return (XPRT_MOREREQS);
-  return (XPRT_IDLE);
+    return XPRT_DIED;
+  if (!INTUSE(xdrrec_eof) (&(cd->xdrs)))
+    return XPRT_MOREREQS;
+  return XPRT_IDLE;
 }
 
 static bool_t
-svctcp_recv (xprt, msg)
-     SVCXPRT *xprt;
-     struct rpc_msg *msg;
+svctcp_recv (SVCXPRT *xprt, struct rpc_msg *msg)
 {
-  struct tcp_conn *cd =
-  (struct tcp_conn *) (xprt->xp_p1);
+  struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1);
   XDR *xdrs = &(cd->xdrs);
 
   xdrs->x_op = XDR_DECODE;
-  (void) xdrrec_skiprecord (xdrs);
-  if (xdr_callmsg (xdrs, msg))
+  (void) INTUSE(xdrrec_skiprecord) (xdrs);
+  if (INTUSE(xdr_callmsg) (xdrs, msg))
     {
       cd->x_id = msg->rm_xid;
-      return (TRUE);
+      return TRUE;
     }
   cd->strm_stat = XPRT_DIED;   /* XXXX */
-  return (FALSE);
+  return FALSE;
 }
 
 static bool_t
-svctcp_getargs (xprt, xdr_args, args_ptr)
-     SVCXPRT *xprt;
-     xdrproc_t xdr_args;
-     caddr_t args_ptr;
+svctcp_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
 {
-
-  return ((*xdr_args) (&(((struct tcp_conn *) (xprt->xp_p1))->xdrs), args_ptr));
+  return ((*xdr_args) (&(((struct tcp_conn *)
+                         (xprt->xp_p1))->xdrs), args_ptr));
 }
 
 static bool_t
-svctcp_freeargs (xprt, xdr_args, args_ptr)
-     SVCXPRT *xprt;
-     xdrproc_t xdr_args;
-     caddr_t args_ptr;
+svctcp_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
 {
-  XDR *xdrs =
-  &(((struct tcp_conn *) (xprt->xp_p1))->xdrs);
+  XDR *xdrs = &(((struct tcp_conn *) (xprt->xp_p1))->xdrs);
 
   xdrs->x_op = XDR_FREE;
   return ((*xdr_args) (xdrs, args_ptr));
 }
 
 static bool_t
-svctcp_reply (xprt, msg)
-     SVCXPRT *xprt;
-     struct rpc_msg *msg;
+svctcp_reply (SVCXPRT *xprt, struct rpc_msg *msg)
 {
-  struct tcp_conn *cd =
-  (struct tcp_conn *) (xprt->xp_p1);
+  struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1);
   XDR *xdrs = &(cd->xdrs);
   bool_t stat;
 
   xdrs->x_op = XDR_ENCODE;
   msg->rm_xid = cd->x_id;
-  stat = xdr_replymsg (xdrs, msg);
-  (void) xdrrec_endofrecord (xdrs, TRUE);
-  return (stat);
+  stat = INTUSE(xdr_replymsg) (xdrs, msg);
+  (void) INTUSE(xdrrec_endofrecord) (xdrs, TRUE);
+  return stat;
 }