fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / sunrpc / svc_tcp.c
index 41f9533..539a2b8 100644 (file)
@@ -44,11 +44,18 @@ 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>
+#endif
+
 /*
  * Ops vector for TCP/IP based rpc service handle
  */
@@ -74,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
 };
 
@@ -134,42 +150,39 @@ svctcp_create (int sock, u_int sendsize, u_int recvsize)
 
   if (sock == RPC_ANYSOCK)
     {
-      if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+      if ((sock = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        {
-         perror (_("svctcp_.c - udp socket creation problem"));
+         perror (_("svc_tcp.c - tcp socket creation problem"));
          return (SVCXPRT *) NULL;
        }
       madesock = TRUE;
     }
-  bzero ((char *) &addr, sizeof (addr));
+  __bzero ((char *) &addr, sizeof (addr));
   addr.sin_family = AF_INET;
   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 (_("svctcp_.c - cannot getsockname or listen"));
+      perror (_("svc_tcp.c - cannot getsockname or listen"));
       if (madesock)
-       (void) close (sock);
+       (void) __close (sock);
       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;
@@ -198,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;
@@ -222,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;
 }
 
@@ -237,8 +245,7 @@ rendezvous_request (SVCXPRT *xprt, struct rpc_msg *errmsg)
   r = (struct tcp_rendezvous *) xprt->xp_p1;
 again:
   len = sizeof (struct sockaddr_in);
-  if ((sock = accept (xprt->xp_sock, (struct sockaddr *) &addr,
-                     &len)) < 0)
+  if ((sock = accept (xprt->xp_sock, (struct sockaddr *) &addr, &len)) < 0)
     {
       if (errno == EINTR)
        goto again;
@@ -248,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 */
 }
@@ -265,7 +272,7 @@ svctcp_destroy (SVCXPRT *xprt)
   struct tcp_conn *cd = (struct tcp_conn *) xprt->xp_p1;
 
   xprt_unregister (xprt);
-  (void) close (xprt->xp_sock);
+  (void) __close (xprt->xp_sock);
   if (xprt->xp_port != 0)
     {
       /* a rendezvouser socket */
@@ -280,12 +287,6 @@ 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.
@@ -297,41 +298,34 @@ readtcp (char *xprtptr, char *buf, int len)
 {
   SVCXPRT *xprt = (SVCXPRT *)xprtptr;
   int sock = xprt->xp_sock;
-#ifdef FD_SETSIZE
-  fd_set mask;
-  fd_set readfds;
-
-  FD_ZERO (&mask);
-  FD_SET (sock, &mask);
-#else
-  int mask = 1 << sock;
-  int readfds;
-#endif /* def FD_SETSIZE */
+  int milliseconds = 35 * 1000;
+  struct pollfd pollfd;
+
   do
     {
-      struct timeval timeout = wait_per_try;
-      readfds = mask;
-      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;
-           }
+           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
-    }
-  while (!FD_ISSET (sock, &readfds));
-#else
     }
-  while (readfds != mask);
-#endif /* def FD_SETSIZE */
-  if ((len = read (sock, buf, len)) > 0)
-    {
-      return len;
-    }
-fatal_err:
+  while ((pollfd.revents & POLLIN) == 0);
+
+  if ((len = __read (sock, buf, len)) > 0)
+    return len;
+
+ fatal_err:
   ((struct tcp_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
   return -1;
 }
@@ -348,14 +342,13 @@ writetcp (char *xprtptr, char * buf, int len)
 
   for (cnt = len; cnt > 0; cnt -= i, buf += i)
     {
-      if ((i = write (xprt->xp_sock, buf, cnt)) < 0)
+      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
@@ -365,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;
 }