diff --git a/lib/libc/rpc/clnt_bcast.c b/lib/libc/rpc/clnt_bcast.c index 5d576f953236..ba4e5883612e 100644 --- a/lib/libc/rpc/clnt_bcast.c +++ b/lib/libc/rpc/clnt_bcast.c @@ -1,4 +1,4 @@ -/* $NetBSD: clnt_bcast.c,v 1.8 2002/09/23 14:12:31 mycroft Exp $ */ +/* $NetBSD: clnt_bcast.c,v 1.9 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -78,7 +78,7 @@ static char sccsid[] = "@(#)clnt_bcast.c 1.15 89/04/21 Copyr 1988 Sun Micro"; #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #define MAXBCAST 20 /* Max no of broadcasting transports */ #define INITTIME 4000 /* Time to wait initially */ diff --git a/lib/libc/rpc/clnt_dg.c b/lib/libc/rpc/clnt_dg.c index d9ab3e2fe496..21fcfaaf9975 100644 --- a/lib/libc/rpc/clnt_dg.c +++ b/lib/libc/rpc/clnt_dg.c @@ -1,4 +1,4 @@ -/* $NetBSD: clnt_dg.c,v 1.7 2001/01/04 14:42:18 lukem Exp $ */ +/* $NetBSD: clnt_dg.c,v 1.8 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -59,7 +59,7 @@ static char sccsid[] = "@(#)clnt_dg.c 1.19 89/03/16 Copyr 1988 Sun Micro"; #include #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(clnt_dg_create,_clnt_dg_create) diff --git a/lib/libc/rpc/clnt_generic.c b/lib/libc/rpc/clnt_generic.c index 8da31b5e23c9..3d2e557e7bd8 100644 --- a/lib/libc/rpc/clnt_generic.c +++ b/lib/libc/rpc/clnt_generic.c @@ -1,4 +1,4 @@ -/* $NetBSD: clnt_generic.c,v 1.19 2001/01/04 14:42:18 lukem Exp $ */ +/* $NetBSD: clnt_generic.c,v 1.20 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -54,7 +54,7 @@ static char sccsid[] = "@(#)clnt_generic.c 1.32 89/03/16 Copyr 1988 Sun Micro"; #include #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(clnt_create_vers,_clnt_create_vers) diff --git a/lib/libc/rpc/clnt_vc.c b/lib/libc/rpc/clnt_vc.c index 473edee3538c..1fc902f15dd7 100644 --- a/lib/libc/rpc/clnt_vc.c +++ b/lib/libc/rpc/clnt_vc.c @@ -1,4 +1,4 @@ -/* $NetBSD: clnt_vc.c,v 1.7 2001/01/04 14:42:19 lukem Exp $ */ +/* $NetBSD: clnt_vc.c,v 1.8 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -36,7 +36,7 @@ static char *sccsid = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC"; static char sccsid[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro"; #else -__RCSID("$NetBSD: clnt_vc.c,v 1.7 2001/01/04 14:42:19 lukem Exp $"); +__RCSID("$NetBSD: clnt_vc.c,v 1.8 2002/11/08 00:13:07 fvdl Exp $"); #endif #endif @@ -77,7 +77,7 @@ __RCSID("$NetBSD: clnt_vc.c,v 1.7 2001/01/04 14:42:19 lukem Exp $"); #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(clnt_vc_create,_clnt_vc_create) diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c index 6cc613af68b4..a166ed97943b 100644 --- a/lib/libc/rpc/getnetconfig.c +++ b/lib/libc/rpc/getnetconfig.c @@ -1,4 +1,4 @@ -/* $NetBSD: getnetconfig.c,v 1.7 2001/07/26 15:05:08 wiz Exp $ */ +/* $NetBSD: getnetconfig.c,v 1.8 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -48,7 +48,7 @@ static char sccsid[] = "@(#)getnetconfig.c 1.12 91/12/19 SMI"; #include #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(getnetconfig,_getnetconfig) diff --git a/lib/libc/rpc/pmap_clnt.c b/lib/libc/rpc/pmap_clnt.c index 8dfdf1f2dc40..5af73c193d93 100644 --- a/lib/libc/rpc/pmap_clnt.c +++ b/lib/libc/rpc/pmap_clnt.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap_clnt.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */ +/* $NetBSD: pmap_clnt.c,v 1.17 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -35,7 +35,7 @@ static char *sccsid = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC"; #else -__RCSID("$NetBSD: pmap_clnt.c,v 1.16 2000/07/06 03:10:34 christos Exp $"); +__RCSID("$NetBSD: pmap_clnt.c,v 1.17 2002/11/08 00:13:07 fvdl Exp $"); #endif #endif @@ -58,7 +58,7 @@ __RCSID("$NetBSD: pmap_clnt.c,v 1.16 2000/07/06 03:10:34 christos Exp $"); #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(pmap_set,_pmap_set) diff --git a/lib/libc/rpc/rpc_com.h b/lib/libc/rpc/rpc_com.h deleted file mode 100644 index 96daf98fb8bc..000000000000 --- a/lib/libc/rpc/rpc_com.h +++ /dev/null @@ -1,84 +0,0 @@ -/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. - */ - -/* - * rpc_com.h, Common definitions for both the server and client side. - * All for the topmost layer of rpc - * - * In Sun's tirpc distribution, this was installed as , - * but as it contains only non-exported interfaces, it was moved here. - */ - -#ifndef _RPC_RPCCOM_H -#define _RPC_RPCCOM_H - -#include - -/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */ - -/* - * The max size of the transport, if the size cannot be determined - * by other means. - */ -#define RPC_MAXDATASIZE 9000 -#define RPC_MAXADDRSIZE 1024 - -#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \ - (u_int32_t)(now)->tv_usec) - -__BEGIN_DECLS -extern u_int __rpc_get_a_size __P((int)); -extern int __rpc_dtbsize __P((void)); -extern struct netconfig * __rpcgettp __P((int)); -extern int __rpc_get_default_domain __P((char **)); - -char *__rpc_taddr2uaddr_af __P((int, const struct netbuf *)); -struct netbuf *__rpc_uaddr2taddr_af __P((int, const char *)); -int __rpc_fixup_addr __P((struct netbuf *, const struct netbuf *)); -int __rpc_sockinfo2netid __P((struct __rpc_sockinfo *, const char **)); -int __rpc_seman2socktype __P((int)); -int __rpc_socktype2seman __P((int)); -void *rpc_nullproc __P((CLIENT *)); -int __rpc_sockisbound __P((int)); - -struct netbuf *__rpcb_findaddr __P((rpcprog_t, rpcvers_t, - const struct netconfig *, - const char *, CLIENT **)); -bool_t __rpc_control __P((int,void *)); - -char *_get_next_token __P((char *, int)); - -__END_DECLS - -#endif /* _RPC_RPCCOM_H */ diff --git a/lib/libc/rpc/rpc_generic.c b/lib/libc/rpc/rpc_generic.c index 829b0ccb6fc3..029e87d2357c 100644 --- a/lib/libc/rpc/rpc_generic.c +++ b/lib/libc/rpc/rpc_generic.c @@ -1,4 +1,4 @@ -/* $NetBSD: rpc_generic.c,v 1.9 2001/11/04 13:57:30 lukem Exp $ */ +/* $NetBSD: rpc_generic.c,v 1.10 2002/11/08 00:13:07 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -57,7 +57,7 @@ #include #include #include -#include "rpc_com.h" +#include "rpc_internal.h" struct handle { NCONF_HANDLE *nhandle; diff --git a/lib/libc/rpc/rpc_internal.h b/lib/libc/rpc/rpc_internal.h new file mode 100644 index 000000000000..78988b746afe --- /dev/null +++ b/lib/libc/rpc/rpc_internal.h @@ -0,0 +1,41 @@ +/* $NetBSD: rpc_internal.h,v 1.1 2002/11/08 00:13:08 fvdl Exp $ */ + +/* + * Private include file for XDR functions only used internally in libc. + * These are not exported interfaces. + */ + +bool_t __xdrrec_getrec __P((XDR *, enum xprt_stat *, bool_t)); +bool_t __xdrrec_setnonblock __P((XDR *, int)); +void __xprt_unregister_unlocked __P((SVCXPRT *)); +bool_t __svc_clean_idle __P((fd_set *, int, bool_t)); + +bool_t __xdrrec_getrec __P((XDR *, enum xprt_stat *, bool_t)); +bool_t __xdrrec_setnonblock __P((XDR *, int)); + +u_int __rpc_get_a_size __P((int)); +int __rpc_dtbsize __P((void)); +struct netconfig * __rpcgettp __P((int)); +int __rpc_get_default_domain __P((char **)); + +char *__rpc_taddr2uaddr_af __P((int, const struct netbuf *)); +struct netbuf *__rpc_uaddr2taddr_af __P((int, const char *)); +int __rpc_fixup_addr __P((struct netbuf *, const struct netbuf *)); +int __rpc_sockinfo2netid __P((struct __rpc_sockinfo *, const char **)); +int __rpc_seman2socktype __P((int)); +int __rpc_socktype2seman __P((int)); +void *rpc_nullproc __P((CLIENT *)); +int __rpc_sockisbound __P((int)); + +struct netbuf *__rpcb_findaddr __P((rpcprog_t, rpcvers_t, + const struct netconfig *, + const char *, CLIENT **)); +bool_t __rpc_control __P((int,void *)); + +char *_get_next_token __P((char *, int)); + +#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \ + (u_int32_t)(now)->tv_usec) + +extern SVCXPRT **__svc_xports; +extern int __svc_maxrec; diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c index a440134f0ad5..b23cabba8997 100644 --- a/lib/libc/rpc/rpc_soc.c +++ b/lib/libc/rpc/rpc_soc.c @@ -1,4 +1,4 @@ -/* $NetBSD: rpc_soc.c,v 1.8 2001/11/04 13:57:30 lukem Exp $ */ +/* $NetBSD: rpc_soc.c,v 1.9 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -72,7 +72,7 @@ static char sccsid[] = "@(#)rpc_soc.c 1.41 89/05/02 Copyr 1988 Sun Micro"; #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(clntudp_bufcreate,_clntudp_bufcreate) diff --git a/lib/libc/rpc/rpcb_clnt.c b/lib/libc/rpc/rpcb_clnt.c index fa0c8e7fbda3..adfe12d83f72 100644 --- a/lib/libc/rpc/rpcb_clnt.c +++ b/lib/libc/rpc/rpcb_clnt.c @@ -1,4 +1,4 @@ -/* $NetBSD: rpcb_clnt.c,v 1.11 2002/10/02 01:22:09 yamt Exp $ */ +/* $NetBSD: rpcb_clnt.c,v 1.12 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -71,7 +71,7 @@ static char sccsid[] = "@(#)rpcb_clnt.c 1.30 89/06/21 Copyr 1988 Sun Micro"; #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(rpcb_set,_rpcb_set) diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c index 1c119d5ba59c..52e061ce21f9 100644 --- a/lib/libc/rpc/svc.c +++ b/lib/libc/rpc/svc.c @@ -1,4 +1,4 @@ -/* $NetBSD: svc.c,v 1.22 2001/01/04 14:42:21 lukem Exp $ */ +/* $NetBSD: svc.c,v 1.23 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -35,7 +35,7 @@ static char *sccsid = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC"; #else -__RCSID("$NetBSD: svc.c,v 1.22 2001/01/04 14:42:21 lukem Exp $"); +__RCSID("$NetBSD: svc.c,v 1.23 2002/11/08 00:13:08 fvdl Exp $"); #endif #endif @@ -63,7 +63,7 @@ __RCSID("$NetBSD: svc.c,v 1.22 2001/01/04 14:42:21 lukem Exp $"); #include #endif -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(svc_getreq,_svc_getreq) @@ -83,9 +83,11 @@ __weak_alias(svcerr_systemerr,_svcerr_systemerr) __weak_alias(svcerr_weakauth,_svcerr_weakauth) __weak_alias(xprt_register,_xprt_register) __weak_alias(xprt_unregister,_xprt_unregister) +__weak_alias(rpc_control,_rpc_control) #endif -static SVCXPRT **xports; +SVCXPRT **__svc_xports; +int __svc_maxrec; #define RQCRED_SIZE 400 /* this size is excessive */ @@ -115,6 +117,7 @@ extern rwlock_t svc_fd_lock; static struct svc_callout *svc_find __P((rpcprog_t, rpcvers_t, struct svc_callout **, char *)); +static void __xprt_do_unregister __P((SVCXPRT *xprt, bool_t dolock)); /* *************** SVCXPRT related stuff **************** */ @@ -132,27 +135,40 @@ xprt_register(xprt) sock = xprt->xp_fd; rwlock_wrlock(&svc_fd_lock); - if (xports == NULL) { - xports = (SVCXPRT **) + if (__svc_xports == NULL) { + __svc_xports = (SVCXPRT **) mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); - if (xports == NULL) + if (__svc_xports == NULL) return; - memset(xports, '\0', FD_SETSIZE * sizeof(SVCXPRT *)); + memset(__svc_xports, '\0', FD_SETSIZE * sizeof(SVCXPRT *)); } if (sock < FD_SETSIZE) { - xports[sock] = xprt; + __svc_xports[sock] = xprt; FD_SET(sock, &svc_fdset); svc_maxfd = max(svc_maxfd, sock); } rwlock_unlock(&svc_fd_lock); } +void +xprt_unregister(SVCXPRT *xprt) +{ + __xprt_do_unregister(xprt, TRUE); +} + +void +__xprt_unregister_unlocked(SVCXPRT *xprt) +{ + __xprt_do_unregister(xprt, FALSE); +} + /* * De-activate a transport handle. */ -void -xprt_unregister(xprt) +static void +__xprt_do_unregister(xprt, dolock) SVCXPRT *xprt; + bool_t dolock; { int sock; @@ -160,17 +176,19 @@ xprt_unregister(xprt) sock = xprt->xp_fd; - rwlock_wrlock(&svc_fd_lock); - if ((sock < FD_SETSIZE) && (xports[sock] == xprt)) { - xports[sock] = NULL; + if (dolock) + rwlock_wrlock(&svc_fd_lock); + if ((sock < FD_SETSIZE) && (__svc_xports[sock] == xprt)) { + __svc_xports[sock] = NULL; FD_CLR(sock, &svc_fdset); if (sock >= svc_maxfd) { for (svc_maxfd--; svc_maxfd>=0; svc_maxfd--) - if (xports[svc_maxfd]) + if (__svc_xports[svc_maxfd]) break; } } - rwlock_unlock(&svc_fd_lock); + if (dolock) + rwlock_unlock(&svc_fd_lock); } /* @@ -646,7 +664,7 @@ svc_getreq_common(fd) r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]); rwlock_rdlock(&svc_fd_lock); - xprt = xports[fd]; + xprt = __svc_xports[fd]; rwlock_unlock(&svc_fd_lock); if (xprt == NULL) /* But do we control sock? */ @@ -702,7 +720,7 @@ svc_getreq_common(fd) * If so, then break. */ rwlock_rdlock(&svc_fd_lock); - if (xprt != xports[fd]) { + if (xprt != __svc_xports[fd]) { rwlock_unlock(&svc_fd_lock); break; } @@ -752,3 +770,24 @@ svc_getreq_poll(pfdp, pollretval) } } } + +bool_t +rpc_control(int what, void *arg) +{ + int val; + + switch (what) { + case RPC_SVC_CONNMAXREC_SET: + val = *(int *)arg; + if (val <= 0) + return FALSE; + __svc_maxrec = val; + return TRUE; + case RPC_SVC_CONNMAXREC_GET: + *(int *)arg = __svc_maxrec; + return TRUE; + default: + break; + } + return FALSE; +} diff --git a/lib/libc/rpc/svc_dg.c b/lib/libc/rpc/svc_dg.c index e0a19a87abd8..243e2949d0ca 100644 --- a/lib/libc/rpc/svc_dg.c +++ b/lib/libc/rpc/svc_dg.c @@ -1,4 +1,4 @@ -/* $NetBSD: svc_dg.c,v 1.6 2001/01/04 14:42:22 lukem Exp $ */ +/* $NetBSD: svc_dg.c,v 1.7 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -59,7 +59,7 @@ #endif #include -#include "rpc_com.h" +#include "rpc_internal.h" #include "svc_dg.h" #define su_data(xprt) ((struct svc_dg_data *)(xprt->xp_p2)) diff --git a/lib/libc/rpc/svc_generic.c b/lib/libc/rpc/svc_generic.c index 5a21da03f7ee..c96b18730a8b 100644 --- a/lib/libc/rpc/svc_generic.c +++ b/lib/libc/rpc/svc_generic.c @@ -1,4 +1,4 @@ -/* $NetBSD: svc_generic.c,v 1.3 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: svc_generic.c,v 1.4 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -60,7 +60,7 @@ static char sccsid[] = "@(#)svc_generic.c 1.21 89/02/28 Copyr 1988 Sun Micro"; #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(svc_create,_svc_create) diff --git a/lib/libc/rpc/svc_run.c b/lib/libc/rpc/svc_run.c index f8622f04f2f8..754b0b594d81 100644 --- a/lib/libc/rpc/svc_run.c +++ b/lib/libc/rpc/svc_run.c @@ -1,4 +1,4 @@ -/* $NetBSD: svc_run.c,v 1.17 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: svc_run.c,v 1.18 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -35,7 +35,7 @@ static char *sccsid = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC"; #else -__RCSID("$NetBSD: svc_run.c,v 1.17 2000/07/06 03:10:35 christos Exp $"); +__RCSID("$NetBSD: svc_run.c,v 1.18 2002/11/08 00:13:08 fvdl Exp $"); #endif #endif @@ -53,6 +53,8 @@ __RCSID("$NetBSD: svc_run.c,v 1.17 2000/07/06 03:10:35 christos Exp $"); #include +#include "rpc_internal.h" + #ifdef __weak_alias __weak_alias(svc_run,_svc_run) __weak_alias(svc_exit,_svc_exit) @@ -61,16 +63,21 @@ __weak_alias(svc_exit,_svc_exit) void svc_run() { - fd_set readfds; + fd_set readfds, cleanfds; + struct timeval timeout; #ifdef __REENT extern rwlock_t svc_fd_lock; #endif + timeout.tv_sec = 30; + timeout.tv_usec = 0; + for (;;) { rwlock_rdlock(&svc_fd_lock); readfds = svc_fdset; + cleanfds = svc_fdset; rwlock_unlock(&svc_fd_lock); - switch (select(svc_maxfd+1, &readfds, NULL, NULL, NULL)) { + switch (select(svc_maxfd+1, &readfds, NULL, NULL, &timeout)) { case -1: if (errno == EINTR) { continue; @@ -78,6 +85,7 @@ svc_run() warn("svc_run: - select failed"); return; case 0: + __svc_clean_idle(&cleanfds, 30, FALSE); continue; default: svc_getreqset(&readfds); diff --git a/lib/libc/rpc/svc_simple.c b/lib/libc/rpc/svc_simple.c index ddc277ccabc8..4f321d636801 100644 --- a/lib/libc/rpc/svc_simple.c +++ b/lib/libc/rpc/svc_simple.c @@ -1,4 +1,4 @@ -/* $NetBSD: svc_simple.c,v 1.21 2001/01/04 14:42:22 lukem Exp $ */ +/* $NetBSD: svc_simple.c,v 1.22 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -57,7 +57,7 @@ #include #include -#include "rpc_com.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(rpc_reg,_rpc_reg) diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c index 2ea69117e067..9c892071b4dc 100644 --- a/lib/libc/rpc/svc_vc.c +++ b/lib/libc/rpc/svc_vc.c @@ -1,4 +1,4 @@ -/* $NetBSD: svc_vc.c,v 1.9 2002/03/03 18:19:41 cjep Exp $ */ +/* $NetBSD: svc_vc.c,v 1.10 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -35,7 +35,7 @@ static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC"; #else -__RCSID("$NetBSD: svc_vc.c,v 1.9 2002/03/03 18:19:41 cjep Exp $"); +__RCSID("$NetBSD: svc_vc.c,v 1.10 2002/11/08 00:13:08 fvdl Exp $"); #endif #endif @@ -54,12 +54,14 @@ __RCSID("$NetBSD: svc_vc.c,v 1.9 2002/03/03 18:19:41 cjep Exp $"); #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -67,7 +69,8 @@ __RCSID("$NetBSD: svc_vc.c,v 1.9 2002/03/03 18:19:41 cjep Exp $"); #include -#include "rpc_com.h" +#include "rpc_internal.h" +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(svc_fd_create,_svc_fd_create) @@ -78,6 +81,7 @@ static SVCXPRT *makefd_xprt __P((int, u_int, u_int)); static bool_t rendezvous_request __P((SVCXPRT *, struct rpc_msg *)); static enum xprt_stat rendezvous_stat __P((SVCXPRT *)); static void svc_vc_destroy __P((SVCXPRT *)); +static void __svc_vc_dodestroy __P((SVCXPRT *)); static int read_vc __P((caddr_t, caddr_t, int)); static int write_vc __P((caddr_t, caddr_t, int)); static enum xprt_stat svc_vc_stat __P((SVCXPRT *)); @@ -88,10 +92,13 @@ static bool_t svc_vc_reply __P((SVCXPRT *, struct rpc_msg *)); static void svc_vc_rendezvous_ops __P((SVCXPRT *)); static void svc_vc_ops __P((SVCXPRT *)); static bool_t svc_vc_control __P((SVCXPRT *xprt, const u_int rq, void *in)); +static bool_t svc_vc_rendezvous_control __P((SVCXPRT *xprt, const u_int rq, + void *in)); struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */ u_int sendsize; u_int recvsize; + int maxrec; }; struct cf_conn { /* kept in xprt->xp_p1 for actual connection */ @@ -99,6 +106,11 @@ struct cf_conn { /* kept in xprt->xp_p1 for actual connection */ u_int32_t x_id; XDR xdrs; char verf_body[MAX_AUTH_BYTES]; + u_int sendsize; + u_int recvsize; + int maxrec; + bool_t nonblock; + struct timeval last_recv_time; }; /* @@ -139,6 +151,7 @@ svc_vc_create(fd, sendsize, recvsize) return NULL; r->sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize); r->recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize); + r->maxrec = __svc_maxrec; xprt = mem_alloc(sizeof(SVCXPRT)); if (xprt == NULL) { warnx("svc_vc_create: out of memory"); @@ -292,11 +305,14 @@ rendezvous_request(xprt, msg) SVCXPRT *xprt; struct rpc_msg *msg; { - int sock; + int sock, flags; struct cf_rendezvous *r; + struct cf_conn *cd; struct sockaddr_storage addr; socklen_t len; struct __rpc_sockinfo si; + SVCXPRT *newxprt; + fd_set cleanfds; _DIAGASSERT(xprt != NULL); _DIAGASSERT(msg != NULL); @@ -308,21 +324,30 @@ again: &len)) < 0) { if (errno == EINTR) goto again; - return (FALSE); + /* + * Clean out the most idle file descriptor when we're + * running out. + */ + if (errno == EMFILE || errno == ENFILE) { + cleanfds = svc_fdset; + __svc_clean_idle(&cleanfds, 0, FALSE); + goto again; + } + return (FALSE); } /* * make a new transporter (re-uses xprt) */ - xprt = makefd_xprt(sock, r->sendsize, r->recvsize); - xprt->xp_rtaddr.buf = mem_alloc(len); - if (xprt->xp_rtaddr.buf == NULL) + newxprt = makefd_xprt(sock, r->sendsize, r->recvsize); + newxprt->xp_rtaddr.buf = mem_alloc(len); + if (newxprt->xp_rtaddr.buf == NULL) return (FALSE); - memcpy(xprt->xp_rtaddr.buf, &addr, len); - xprt->xp_rtaddr.len = len; + memcpy(newxprt->xp_rtaddr.buf, &addr, len); + newxprt->xp_rtaddr.len = len; #ifdef PORTMAP if (addr.ss_family == AF_INET) { - xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; - xprt->xp_addrlen = sizeof (struct sockaddr_in); + newxprt->xp_raddr = *(struct sockaddr_in *)newxprt->xp_rtaddr.buf; + newxprt->xp_addrlen = sizeof (struct sockaddr_in); } #endif if (__rpc_fd2sockinfo(sock, &si) && si.si_proto == IPPROTO_TCP) { @@ -330,6 +355,28 @@ again: /* XXX fvdl - is this useful? */ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &len, sizeof (len)); } + + cd = (struct cf_conn *)newxprt->xp_p1; + + cd->recvsize = r->recvsize; + cd->sendsize = r->sendsize; + cd->maxrec = r->maxrec; + + if (cd->maxrec != 0) { + flags = fcntl(sock, F_GETFL, 0); + if (flags == -1) + return (FALSE); + if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) + return (FALSE); + if (cd->recvsize > cd->maxrec) + cd->recvsize = cd->maxrec; + cd->nonblock = TRUE; + __xdrrec_setnonblock(&cd->xdrs, cd->maxrec); + } else + cd->nonblock = FALSE; + + gettimeofday(&cd->last_recv_time, NULL); + return (FALSE); /* there is never an rpc msg to be processed */ } @@ -345,15 +392,22 @@ rendezvous_stat(xprt) static void svc_vc_destroy(xprt) SVCXPRT *xprt; +{ + _DIAGASSERT(xprt != NULL); + + xprt_unregister(xprt); + __svc_vc_dodestroy(xprt); +} + +static void +__svc_vc_dodestroy(xprt) + SVCXPRT *xprt; { struct cf_conn *cd; struct cf_rendezvous *r; - _DIAGASSERT(xprt != NULL); - cd = (struct cf_conn *)xprt->xp_p1; - xprt_unregister(xprt); if (xprt->xp_fd != RPC_ANYFD) (void)close(xprt->xp_fd); if (xprt->xp_port != 0) { @@ -387,6 +441,31 @@ svc_vc_control(xprt, rq, in) return (FALSE); } +/*ARGSUSED*/ +static bool_t +svc_vc_rendezvous_control(xprt, rq, in) + SVCXPRT *xprt; + const u_int rq; + void *in; +{ + struct cf_rendezvous *cfp; + + cfp = (struct cf_rendezvous *)xprt->xp_p1; + if (cfp == NULL) + return (FALSE); + switch (rq) { + case SVCGET_CONNMAXREC: + *(int *)in = cfp->maxrec; + break; + case SVCSET_CONNMAXREC: + cfp->maxrec = *(int *)in; + break; + default: + return (FALSE); + } + return (TRUE); +} + /* * reads data from the tcp connection. * any error is fatal and the connection is closed. @@ -410,6 +489,7 @@ read_vc(xprtp, buf, len) void *crmsg = NULL; struct sockcred *sc; socklen_t crmsgsize; + struct cf_conn *cfp; xprt = (SVCXPRT *)(void *)xprtp; _DIAGASSERT(xprt != NULL); @@ -450,7 +530,22 @@ read_vc(xprtp, buf, len) free(crmsg); crmsg = NULL; } - + + cfp = (struct cf_conn *)xprt->xp_p1; + + if (cfp->nonblock) { + len = read(sock, buf, (size_t)len); + if (len < 0) { + if (errno == EAGAIN) + len = 0; + else + goto fatal_err; + } + if (len != 0) + gettimeofday(&cfp->last_recv_time, NULL); + return len; + } + do { pollfd.fd = sock; pollfd.events = POLLIN; @@ -468,8 +563,10 @@ read_vc(xprtp, buf, len) } } while ((pollfd.revents & POLLIN) == 0); - if ((len = read(sock, buf, (size_t)len)) > 0) + if ((len = read(sock, buf, (size_t)len)) > 0) { + gettimeofday(&cfp->last_recv_time, NULL); return (len); + } fatal_err: if (crmsg != NULL) @@ -490,15 +587,37 @@ write_vc(xprtp, buf, len) { SVCXPRT *xprt; int i, cnt; + struct cf_conn *cd; + struct timeval tv0, tv1; xprt = (SVCXPRT *)(void *)xprtp; _DIAGASSERT(xprt != NULL); + cd = (struct cf_conn *)xprt->xp_p1; + + if (cd->nonblock) + gettimeofday(&tv0, NULL); + for (cnt = len; cnt > 0; cnt -= i, buf += i) { if ((i = write(xprt->xp_fd, buf, (size_t)cnt)) < 0) { - ((struct cf_conn *)(xprt->xp_p1))->strm_stat = - XPRT_DIED; - return (-1); + if (errno != EAGAIN || !cd->nonblock) { + cd->strm_stat = XPRT_DIED; + return (-1); + } + if (cd->nonblock && i != cnt) { + /* + * For non-blocking connections, do not + * take more than 2 seconds writing the + * data out. + * + * XXX 2 is an arbitrary amount. + */ + gettimeofday(&tv1, NULL); + if (tv1.tv_sec - tv0.tv_sec >= 2) { + cd->strm_stat = XPRT_DIED; + return (-1); + } + } } } return (len); @@ -535,8 +654,14 @@ svc_vc_recv(xprt, msg) cd = (struct cf_conn *)(xprt->xp_p1); xdrs = &(cd->xdrs); + if (cd->nonblock) { + if (!__xdrrec_getrec(xdrs, &cd->strm_stat, TRUE)) + return FALSE; + } + xdrs->x_op = XDR_DECODE; (void)xdrrec_skiprecord(xdrs); + if (xdr_callmsg(xdrs, msg)) { cd->x_id = msg->rm_xid; return (TRUE); @@ -583,7 +708,7 @@ svc_vc_reply(xprt, msg) { struct cf_conn *cd; XDR *xdrs; - bool_t stat; + bool_t rstat; _DIAGASSERT(xprt != NULL); _DIAGASSERT(msg != NULL); @@ -593,9 +718,9 @@ svc_vc_reply(xprt, msg) xdrs->x_op = XDR_ENCODE; msg->rm_xid = cd->x_id; - stat = xdr_replymsg(xdrs, msg); + rstat = xdr_replymsg(xdrs, msg); (void)xdrrec_endofrecord(xdrs, TRUE); - return (stat); + return (rstat); } static void @@ -646,9 +771,59 @@ svc_vc_rendezvous_ops(xprt) ops.xp_freeargs = (bool_t (*) __P((SVCXPRT *, xdrproc_t, caddr_t)))abort, ops.xp_destroy = svc_vc_destroy; - ops2.xp_control = svc_vc_control; + ops2.xp_control = svc_vc_rendezvous_control; } xprt->xp_ops = &ops; xprt->xp_ops2 = &ops2; mutex_unlock(&ops_lock); } + +/* + * Destroy xprts that have not have had any activity in 'timeout' seconds. + * If 'cleanblock' is true, blocking connections (the default) are also + * cleaned. If timeout is 0, the least active connection is picked. + */ +bool_t +__svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) +{ + int i, ncleaned; + SVCXPRT *xprt, *least_active; + struct timeval tv, tdiff, tmax; + struct cf_conn *cd; + + gettimeofday(&tv, NULL); + tmax.tv_sec = tmax.tv_usec = 0; + least_active = NULL; + rwlock_wrlock(&svc_fd_lock); + for (i = ncleaned = 0; i <= svc_maxfd; i++) { + if (FD_ISSET(i, fds)) { + xprt = __svc_xports[i]; + if (xprt == NULL || xprt->xp_ops == NULL || + xprt->xp_ops->xp_recv != svc_vc_recv) + continue; + cd = (struct cf_conn *)xprt->xp_p1; + if (!cleanblock && !cd->nonblock) + continue; + if (timeout == 0) { + timersub(&tv, &cd->last_recv_time, &tdiff); + if (timercmp(&tdiff, &tmax, >)) { + tmax = tdiff; + least_active = xprt; + } + continue; + } + if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) { + __xprt_unregister_unlocked(xprt); + __svc_vc_dodestroy(xprt); + ncleaned++; + } + } + } + if (timeout == 0 && least_active != NULL) { + __xprt_unregister_unlocked(least_active); + __svc_vc_dodestroy(least_active); + ncleaned++; + } + rwlock_unlock(&svc_fd_lock); + return ncleaned > 0 ? TRUE : FALSE; +} diff --git a/lib/libc/rpc/xdr_rec.c b/lib/libc/rpc/xdr_rec.c index f0ba1fbd0a2b..067e0cf98218 100644 --- a/lib/libc/rpc/xdr_rec.c +++ b/lib/libc/rpc/xdr_rec.c @@ -1,4 +1,4 @@ -/* $NetBSD: xdr_rec.c,v 1.18 2000/07/06 03:10:35 christos Exp $ */ +/* $NetBSD: xdr_rec.c,v 1.19 2002/11/08 00:13:08 fvdl Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -35,7 +35,7 @@ static char *sccsid = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC"; #else -__RCSID("$NetBSD: xdr_rec.c,v 1.18 2000/07/06 03:10:35 christos Exp $"); +__RCSID("$NetBSD: xdr_rec.c,v 1.19 2002/11/08 00:13:08 fvdl Exp $"); #endif #endif @@ -63,12 +63,18 @@ __RCSID("$NetBSD: xdr_rec.c,v 1.18 2000/07/06 03:10:35 christos Exp $"); #include #include +#include #include #include #include #include #include +#include +#include +#include + +#include "rpc_internal.h" #ifdef __weak_alias __weak_alias(xdrrec_create,_xdrrec_create) @@ -100,7 +106,7 @@ static const struct xdr_ops xdrrec_ops = { /* * A record is composed of one or more record fragments. - * A record fragment is a two-byte header followed by zero to + * A record fragment is a four-byte header followed by zero to * 2**32-1 bytes. The header is treated as a long unsigned and is * encode/decoded to the network via htonl/ntohl. The low order 31 bits * are a byte count of the fragment. The highest order bit is a boolean: @@ -115,7 +121,6 @@ static const struct xdr_ops xdrrec_ops = { typedef struct rec_strm { char *tcp_handle; - char *the_buffer; /* * out-goung bits */ @@ -137,6 +142,15 @@ typedef struct rec_strm { bool_t last_frag; u_int sendsize; u_int recvsize; + + bool_t nonblock; + bool_t in_haveheader; + u_int32_t in_header; + char *in_hdrp; + int in_hdrlen; + int in_reclen; + int in_received; + int in_maxrec; } RECSTREAM; static u_int fix_buf_size __P((u_int)); @@ -145,6 +159,7 @@ static bool_t fill_input_buf __P((RECSTREAM *)); static bool_t get_input_bytes __P((RECSTREAM *, char *, int)); static bool_t set_input_fragment __P((RECSTREAM *)); static bool_t skip_input_bytes __P((RECSTREAM *, long)); +static bool_t realloc_stream __P((RECSTREAM *, int)); /* @@ -177,20 +192,23 @@ xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit) */ return; } - /* - * adjust sizes and allocate buffer quad byte aligned - */ + rstrm->sendsize = sendsize = fix_buf_size(sendsize); - rstrm->recvsize = recvsize = fix_buf_size(recvsize); - rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); - if (rstrm->the_buffer == NULL) { + rstrm->out_base = mem_alloc(rstrm->sendsize); + if (rstrm->out_base == NULL) { warnx("xdrrec_create: out of memory"); + mem_free(rstrm, sizeof(RECSTREAM)); + return; + } + + rstrm->recvsize = recvsize = fix_buf_size(recvsize); + rstrm->in_base = mem_alloc(recvsize); + if (rstrm->in_base == NULL) { + warnx("xdrrec_create: out of memory"); + mem_free(rstrm->out_base, sendsize); + mem_free(rstrm, sizeof(RECSTREAM)); return; } - for (rstrm->out_base = rstrm->the_buffer; - (u_long)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; - rstrm->out_base++); - rstrm->in_base = rstrm->out_base + sendsize; /* * now the rest ... */ @@ -209,6 +227,12 @@ xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit) rstrm->in_finger = (rstrm->in_boundry += recvsize); rstrm->fbtbc = 0; rstrm->last_frag = TRUE; + rstrm->in_haveheader = FALSE; + rstrm->in_hdrlen = 0; + rstrm->in_hdrp = (char *)(void *)&rstrm->in_header; + rstrm->nonblock = FALSE; + rstrm->in_reclen = 0; + rstrm->in_received = 0; } @@ -422,8 +446,8 @@ xdrrec_destroy(xdrs) { RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; - mem_free(rstrm->the_buffer, - rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); + mem_free(rstrm->out_base, rstrm->sendsize); + mem_free(rstrm->in_base, rstrm->recvsize); mem_free(rstrm, sizeof(RECSTREAM)); } @@ -441,7 +465,20 @@ xdrrec_skiprecord(xdrs) XDR *xdrs; { RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + enum xprt_stat xstat; + if (rstrm->nonblock) { + if (__xdrrec_getrec(xdrs, &xstat, FALSE)) { + rstrm->fbtbc = 0; + return TRUE; + } + if (rstrm->in_finger == rstrm->in_boundry && + xstat == XPRT_MOREREQS) { + rstrm->fbtbc = 0; + return TRUE; + } + return FALSE; + } while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { if (! skip_input_bytes(rstrm, rstrm->fbtbc)) return (FALSE); @@ -463,12 +500,21 @@ xdrrec_eof(xdrs) XDR *xdrs; { RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + enum xprt_stat xstat; + + if (rstrm->nonblock) { + if (__xdrrec_getrec(xdrs, &xstat, FALSE)) + return FALSE; + if (!rstrm->in_haveheader && xstat == XPRT_IDLE) + return TRUE; + return FALSE; + } while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { - if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + if (!skip_input_bytes(rstrm, rstrm->fbtbc)) return (TRUE); rstrm->fbtbc = 0; - if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + if ((!rstrm->last_frag) && (!set_input_fragment(rstrm))) return (TRUE); } if (rstrm->in_finger == rstrm->in_boundry) @@ -504,6 +550,100 @@ xdrrec_endofrecord(xdrs, sendnow) return (TRUE); } +/* + * Fill the stream buffer with a record for a non-blocking connection. + * Return true if a record is available in the buffer, false if not. + */ +bool_t +__xdrrec_getrec(xdrs, statp, expectdata) + XDR *xdrs; + enum xprt_stat *statp; + bool_t expectdata; +{ + RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + ssize_t n; + int fraglen; + + if (!rstrm->in_haveheader) { + n = rstrm->readit(rstrm->tcp_handle, rstrm->in_hdrp, + (int)sizeof (rstrm->in_header) - rstrm->in_hdrlen); + if (n == 0) { + *statp = expectdata ? XPRT_DIED : XPRT_IDLE; + return FALSE; + } + if (n < 0) { + *statp = XPRT_DIED; + return FALSE; + } + rstrm->in_hdrp += n; + rstrm->in_hdrlen += n; + if (rstrm->in_hdrlen < sizeof (rstrm->in_header)) { + *statp = XPRT_MOREREQS; + return FALSE; + } + rstrm->in_header = ntohl(rstrm->in_header); + fraglen = (int)(rstrm->in_header & ~LAST_FRAG); + if (fraglen == 0 || fraglen > rstrm->in_maxrec || + (rstrm->in_reclen + fraglen) > rstrm->in_maxrec) { + *statp = XPRT_DIED; + return FALSE; + } + rstrm->in_reclen += fraglen; + if (rstrm->in_reclen > rstrm->recvsize) + realloc_stream(rstrm, rstrm->in_reclen); + if (rstrm->in_header & LAST_FRAG) { + rstrm->in_header &= ~LAST_FRAG; + rstrm->last_frag = TRUE; + } + } + + n = rstrm->readit(rstrm->tcp_handle, + rstrm->in_base + rstrm->in_received, + (rstrm->in_reclen - rstrm->in_received)); + + if (n < 0) { + *statp = XPRT_DIED; + return FALSE; + } + + if (n == 0) { + *statp = expectdata ? XPRT_DIED : XPRT_IDLE; + return FALSE; + } + + rstrm->in_received += n; + + if (rstrm->in_received == rstrm->in_reclen) { + rstrm->in_haveheader = FALSE; + rstrm->in_hdrp = (char *)(void *)&rstrm->in_header; + rstrm->in_hdrlen = 0; + if (rstrm->last_frag) { + rstrm->fbtbc = rstrm->in_reclen; + rstrm->in_boundry = rstrm->in_base + rstrm->in_reclen; + rstrm->in_finger = rstrm->in_base; + *statp = XPRT_MOREREQS; + return TRUE; + } + } + + *statp = XPRT_MOREREQS; + return FALSE; +} + +bool_t +__xdrrec_setnonblock(xdrs, maxrec) + XDR *xdrs; + int maxrec; +{ + RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + rstrm->nonblock = TRUE; + if (maxrec == 0) + maxrec = rstrm->recvsize; + rstrm->in_maxrec = maxrec; + return TRUE; +} + /* * Internal useful routines @@ -536,6 +676,8 @@ fill_input_buf(rstrm) u_int32_t i; int len; + if (rstrm->nonblock) + return FALSE; where = rstrm->in_base; i = (u_int32_t)((u_long)rstrm->in_boundry % BYTES_PER_XDR_UNIT); where += i; @@ -556,6 +698,14 @@ get_input_bytes(rstrm, addr, len) { size_t current; + if (rstrm->nonblock) { + if (len > rstrm->in_reclen) + return FALSE; + memcpy(addr, rstrm->in_finger, (size_t)len); + rstrm->in_finger += len; + return TRUE; + } + while (len > 0) { current = (size_t)((long)rstrm->in_boundry - (long)rstrm->in_finger); @@ -579,6 +729,8 @@ set_input_fragment(rstrm) { u_int32_t header; + if (rstrm->nonblock) + return FALSE; if (! get_input_bytes(rstrm, (char *)(void *)&header, sizeof(header))) return (FALSE); header = ntohl(header); @@ -628,3 +780,29 @@ fix_buf_size(s) s = 4000; return (RNDUP(s)); } + +/* + * Reallocate the input buffer for a non-block stream. + */ +static bool_t +realloc_stream(rstrm, size) + RECSTREAM *rstrm; + int size; +{ + ptrdiff_t diff; + char *buf; + + if (size > rstrm->recvsize) { + buf = realloc(rstrm->in_base, (size_t)size); + if (buf == NULL) + return FALSE; + diff = buf - rstrm->in_base; + rstrm->in_finger += diff; + rstrm->in_base = buf; + rstrm->in_boundry = buf + size; + rstrm->recvsize = size; + rstrm->in_size = size; + } + + return TRUE; +}