Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 18 Nov 1998 11:05:09 +0000 (11:05 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 18 Nov 1998 11:05:09 +0000 (11:05 +0000)
1998-11-18  Ulrich Drepper  <drepper@cygnus.com>

* io/Makefile (CFLAGS-ftw.c): Removed.

1998-11-18  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>

* io/Makefile (tests): Make sure that the test program has an
explicit directory part.

1998-11-18  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>

* configure.in: Fix last change.

1998-11-18  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

* sunrpc/Makefile (routines): Add create_xid.

* sunrpc/clnt_tcp.c: Use non-guessable xid.
* sunrpc/clnt_udp.c: Likewise.
* sunrpc/clnt_unix.c: Likewise.
* sunrpc/pmap_rmt.c: Likewise.
* sunrpc/create_xid.c: New, create non-guessable xid.

* sunrpc/svc_tcp.c: Remove patch from 1998-06-15, use poll instead
of select.
* sunrpc/svc_unix.c: Use poll instead of select.

12 files changed:
ChangeLog
configure
configure.in
io/Makefile
sunrpc/Makefile
sunrpc/clnt_tcp.c
sunrpc/clnt_udp.c
sunrpc/clnt_unix.c
sunrpc/create_xid.c [new file with mode: 0644]
sunrpc/pmap_rmt.c
sunrpc/svc_tcp.c
sunrpc/svc_unix.c

index be1a379..99e5ad0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+1998-11-18  Ulrich Drepper  <drepper@cygnus.com>
+
+       * io/Makefile (CFLAGS-ftw.c): Removed.
+
+1998-11-18  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
+
+       * io/Makefile (tests): Make sure that the test program has an
+       explicit directory part.
+
+1998-11-18  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
+
+       * configure.in: Fix last change.
+
+1998-11-18  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+       * sunrpc/Makefile (routines): Add create_xid.
+
+       * sunrpc/clnt_tcp.c: Use non-guessable xid.
+       * sunrpc/clnt_udp.c: Likewise.
+       * sunrpc/clnt_unix.c: Likewise.
+       * sunrpc/pmap_rmt.c: Likewise.
+       * sunrpc/create_xid.c: New, create non-guessable xid.
+
+       * sunrpc/svc_tcp.c: Remove patch from 1998-06-15, use poll instead
+       of select.
+       * sunrpc/svc_unix.c: Use poll instead of select.
+
 1998-11-17  Ulrich Drepper  <drepper@cygnus.com>
 
        * sysdeps/unix/sysv/linux/sleep.c (__sleep): Make Unix98 compliant
index 75c7856..2281a6a 100755 (executable)
--- a/configure
+++ b/configure
@@ -1432,7 +1432,7 @@ echo "configure:1432: checking version of $MAKEINFO" >&5
   ac_prog_version=`$MAKEINFO --version 2>&1 | sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
   case $ac_prog_version in
     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
-    1.6[89] | 1.7[0-9])
+    3.1[1-9] | 3.[2-9][0-9] | 1.6[89] | 1.7[0-9])
        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
     *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
 
index befa6d6..a8dd26a 100644 (file)
@@ -451,7 +451,7 @@ AC_CHECK_PROG_VER(MSGFMT, msgfmt gmsgfmt, --version,
   [0.[1-9][0-9].* | [1-9].*], MSGFMT=: aux_missing=t)
 AC_CHECK_PROG_VER(MAKEINFO, makeinfo, --version,
   [GNU texinfo.* \([0-9][0-9.]*\)],
-  [1.6[89] | 1.7[0-9]], MAKEINFO=: aux_missing=t)
+  [3.1[1-9] | 3.[2-9][0-9] | 1.6[89] | 1.7[0-9]], MAKEINFO=: aux_missing=t)
 
 if test -n "$critic_missing"; then
 AC_MSG_ERROR([
index f8597f5..9f08476 100644 (file)
@@ -60,9 +60,8 @@ distribute    := ftwtest-sh
 include ../Rules
 
 CFLAGS-fts.c = -Wno-uninitialized
-CFLAGS-ftw.c = -Wno-uninitialized
 
 ifeq ($(cross-compiling),no)
 tests: $(objpfx)ftwtest
-       $(SHELL) -e ftwtest-sh $(common-objpfx) $<
+       $(SHELL) -e ftwtest-sh $(common-objpfx) $(<D)/$(<F)
 endif
index 2a6614c..0a327ea 100644 (file)
@@ -67,7 +67,7 @@ routines := auth_none auth_unix authuxprot bindrsvprt \
            xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \
            auth_des authdes_prot des_crypt des_impl des_soft \
            key_call key_prot netname openchild rtime svcauth_des xcrypt\
-           clnt_unix svc_unix
+           clnt_unix svc_unix create_xid
 
 others := rpcinfo
 install-bin := rpcgen
index 07224e3..abb2849 100644 (file)
@@ -59,6 +59,8 @@ static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
 #include <sys/socket.h>
 #include <rpc/pmap_clnt.h>
 
+extern u_long _create_xid (void);
+
 #define MCALL_MSG_SIZE 24
 
 struct ct_data
@@ -115,7 +117,6 @@ clnttcp_create (struct sockaddr_in *raddr, u_long prog, u_long vers,
 {
   CLIENT *h;
   struct ct_data *ct = (struct ct_data *) mem_alloc (sizeof (*ct));
-  struct timeval now;
   struct rpc_msg call_msg;
 
   h = (CLIENT *) mem_alloc (sizeof (*h));
@@ -185,8 +186,7 @@ clnttcp_create (struct sockaddr_in *raddr, u_long prog, u_long vers,
   /*
    * Initialize call message
    */
-  (void) __gettimeofday (&now, (struct timezone *) 0);
-  call_msg.rm_xid = __getpid () ^ now.tv_sec ^ now.tv_usec;
+  call_msg.rm_xid = _create_xid ();
   call_msg.rm_direction = CALL;
   call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
   call_msg.rm_call.cb_prog = prog;
index 0842e5a..ec63f60 100644 (file)
@@ -50,6 +50,7 @@ static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
 #include <rpc/pmap_clnt.h>
 
 extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *);
+extern u_long _create_xid (void);
 
 /*
  * UDP bases client side rpc operations
@@ -109,18 +110,12 @@ struct cu_data
  * sent and received.
  */
 CLIENT *
-clntudp_bufcreate (raddr, program, version, wait, sockp, sendsz, recvsz)
-     struct sockaddr_in *raddr;
-     u_long program;
-     u_long version;
-     struct timeval wait;
-     int *sockp;
-     u_int sendsz;
-     u_int recvsz;
+clntudp_bufcreate (struct sockaddr_in *raddr, u_long program, u_long version,
+                  struct timeval wait, int *sockp, u_int sendsz,
+                  u_int recvsz)
 {
   CLIENT *cl;
   struct cu_data *cu = NULL;
-  struct timeval now;
   struct rpc_msg call_msg;
 
   cl = (CLIENT *) mem_alloc (sizeof (CLIENT));
@@ -143,7 +138,6 @@ clntudp_bufcreate (raddr, program, version, wait, sockp, sendsz, recvsz)
     }
   cu->cu_outbuf = &cu->cu_inbuf[recvsz];
 
-  (void) __gettimeofday (&now, (struct timezone *) 0);
   if (raddr->sin_port == 0)
     {
       u_short port;
@@ -163,7 +157,7 @@ clntudp_bufcreate (raddr, program, version, wait, sockp, sendsz, recvsz)
   cu->cu_total.tv_usec = -1;
   cu->cu_sendsz = sendsz;
   cu->cu_recvsz = recvsz;
-  call_msg.rm_xid = __getpid () ^ now.tv_sec ^ now.tv_usec;
+  call_msg.rm_xid = _create_xid ();
   call_msg.rm_direction = CALL;
   call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
   call_msg.rm_call.cb_prog = program;
index f5d06ce..365bdac 100644 (file)
@@ -56,6 +56,8 @@
 #include <sys/socket.h>
 #include <rpc/pmap_clnt.h>
 
+extern u_long _create_xid (void);
+
 #define MCALL_MSG_SIZE 24
 
 struct ct_data
@@ -112,7 +114,6 @@ clntunix_create (struct sockaddr_un *raddr, u_long prog, u_long vers,
 {
   CLIENT *h;
   struct ct_data *ct = (struct ct_data *) mem_alloc (sizeof (*ct));
-  struct timeval now;
   struct rpc_msg call_msg;
   int len;
 
@@ -167,8 +168,7 @@ clntunix_create (struct sockaddr_un *raddr, u_long prog, u_long vers,
   /*
    * Initialize call message
    */
-  __gettimeofday (&now, (struct timezone *) 0);
-  call_msg.rm_xid = __getpid () ^ now.tv_sec ^ now.tv_usec;
+  call_msg.rm_xid = _create_xid ();
   call_msg.rm_direction = CALL;
   call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
   call_msg.rm_call.cb_prog = prog;
diff --git a/sunrpc/create_xid.c b/sunrpc/create_xid.c
new file mode 100644 (file)
index 0000000..15fb367
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright (c) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <bits/libc-lock.h>
+
+/* The RPC code is not threadsafe, but new code should be threadsafe. */
+
+__libc_lock_define_initialized (static, createxid_lock)
+
+static int is_initialized;
+static struct drand48_data __rpc_lrand48_data;
+
+unsigned long
+_create_xid (void)
+{
+  unsigned long res;
+
+  __libc_lock_lock (createxid_lock);
+
+  if (!is_initialized)
+    {
+      struct timeval now;
+
+      __gettimeofday (&now, (struct timezone *) 0);
+      srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data);
+      is_initialized = 1;
+    }
+
+  lrand48_r (&__rpc_lrand48_data, &res);
+
+  __libc_lock_unlock (createxid_lock);
+
+  return res;
+}
index ced817d..e0f52c9 100644 (file)
@@ -56,6 +56,8 @@ static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";
 #include <arpa/inet.h>
 #define MAX_BROADCAST_SIZE 1400
 
+extern u_long _create_xid (void);
+
 static struct timeval timeout = {3, 0};
 
 /*
@@ -112,9 +114,7 @@ pmap_rmtcall (addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_p
  * written for XDR_ENCODE direction only
  */
 bool_t
-xdr_rmtcall_args (xdrs, cap)
-     XDR *xdrs;
-     struct rmtcallargs *cap;
+xdr_rmtcall_args (XDR *xdrs, struct rmtcallargs *cap)
 {
   u_int lenposition, argposition, position;
 
@@ -237,6 +237,7 @@ clnt_broadcast (prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
   AUTH *unix_auth = authunix_create_default ();
   XDR xdr_stream;
   XDR *xdrs = &xdr_stream;
+  struct timeval t;
   int outlen, inlen, nets;
   socklen_t fromlen;
   int sock;
@@ -252,7 +253,6 @@ clnt_broadcast (prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
   struct rmtcallargs a;
   struct rmtcallres r;
   struct rpc_msg msg;
-  struct timeval t;
   char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
 
   /*
@@ -281,8 +281,7 @@ clnt_broadcast (prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
   baddr.sin_port = htons (PMAPPORT);
   baddr.sin_addr.s_addr = htonl (INADDR_ANY);
 /*      baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */
-  (void) __gettimeofday (&t, (struct timezone *) 0);
-  msg.rm_xid = xid = __getpid () ^ t.tv_sec ^ t.tv_usec;
+  msg.rm_xid = xid = _create_xid ();
   t.tv_usec = 0;
   msg.rm_direction = CALL;
   msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
index 0c2ce96..cd5cecf 100644 (file)
@@ -46,6 +46,7 @@ static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
 #include <string.h>
 #include <rpc/rpc.h>
 #include <sys/socket.h>
+#include <sys/poll.h>
 #include <errno.h>
 #include <stdlib.h>
 
@@ -284,66 +285,42 @@ 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;
-       }
-
-#ifdef FD_SETSIZE
-      if (FD_ISSET (sock, &readfds))
-#else
-      if (readfds == mask)
-#endif /* def FD_SETSIZE */
-       break;
-
-      svc_getreqset (&readfds);
+       default:
+         break;
+         }
     }
+  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 +339,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,19 +353,16 @@ svctcp_stat (SVCXPRT *xprt)
   (struct tcp_conn *) (xprt->xp_p1);
 
   if (cd->strm_stat == XPRT_DIED)
-    return (XPRT_DIED);
+    return XPRT_DIED;
   if (!xdrrec_eof (&(cd->xdrs)))
-    return (XPRT_MOREREQS);
-  return (XPRT_IDLE);
+    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;
@@ -397,42 +370,32 @@ svctcp_recv (xprt, msg)
   if (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;
 
@@ -440,5 +403,5 @@ svctcp_reply (xprt, msg)
   msg->rm_xid = cd->x_id;
   stat = xdr_replymsg (xdrs, msg);
   (void) xdrrec_endofrecord (xdrs, TRUE);
-  return (stat);
+  return stat;
 }
index 9ee64d0..4fba428 100644 (file)
@@ -43,6 +43,7 @@
 #include <rpc/rpc.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
+#include <sys/poll.h>
 #include <errno.h>
 #include <stdlib.h>
 
@@ -352,12 +353,6 @@ __msgwrite (int sock, void *buf, size_t cnt)
 }
 
 /*
- * 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 unix connection.
  * any error is fatal and the connection is closed.
  * (And a read of zero bytes is a half closed stream => error.)
@@ -367,38 +362,26 @@ readunix (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:
+         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 = __msgread (sock, buf, len)) > 0)
     return len;
@@ -471,10 +454,7 @@ svcunix_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
 }
 
 static bool_t
-svcunix_freeargs (xprt, xdr_args, args_ptr)
-     SVCXPRT *xprt;
-     xdrproc_t xdr_args;
-     caddr_t args_ptr;
+svcunix_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
 {
   XDR *xdrs = &(((struct unix_conn *) (xprt->xp_p1))->xdrs);
 
@@ -483,9 +463,7 @@ svcunix_freeargs (xprt, xdr_args, args_ptr)
 }
 
 static bool_t
-svcunix_reply (xprt, msg)
-     SVCXPRT *xprt;
-     struct rpc_msg *msg;
+svcunix_reply (SVCXPRT *xprt, struct rpc_msg *msg)
 {
   struct unix_conn *cd = (struct unix_conn *) (xprt->xp_p1);
   XDR *xdrs = &(cd->xdrs);