ONC+ Developer's Guide

Memory Requirements for XDR Routines

When using XDR routines, you sometimes need to to pre-allocate memory, or to determine memory requirements. When you need to control the allocation and de-allocation of memory for XDR conversion routines, you can use a routine, xdr_sizeof(). This routine returns the number of bytes needed to encode and decode data with one of the XDR filter functions (func()). The output of the xdr_sizeof() function does not include RPC headers or record markers. You must add them to get a complete accounting of the memory required. xdr_sizeof() returns a zero on error.

xdr_sizeof(xdrproc_t func, void *data)

Use xdr_sizeof() for the allocation of memory in applications that use XDR outside of the RPC environment, to select between transport protocols, and at the lower levels of RPC to perform client and server creation functions.

The next two code examples illustrate two uses of xdr_sizeof().


Example A–5 xdr_sizeof Example #1

#include <rpc/rpc.h>
 
/*
 *	This function takes as input a CLIENT handle, an XDR function
and
 *	a pointer to data to be XDR'd. It returns TRUE if the amount of
 *	data to be XDR'd may be sent using the transport associated
with
 *	the CLIENT handle, and false otherwise.
 */
bool_t
cansend(cl, xdrfunc, xdrdata)
	CLIENT *cl;
	xdrproc_t xdrfunc;
	void   *xdrdata;
{
	int fd;
	struct t_info tinfo;
 
	if (clnt_control(cl, CLGET_FD, &fd) == -1) {
		/* handle clnt_control() error */
		return (FALSE);
	}
 
	if (t_getinfo(fd, &tinfo) == -1) {
		/* handle t_getinfo() error */
		return (FALSE);
	} else {
		if (tinfo.servtype == T_CLTS) {
			/*
			 * This is a connectionless transport. Use xdr_sizeof()
			 * to compute the size of this request to see whether it
			 * is too large for this transport.
			 */
			switch(tinfo.tsdu) {
				case 0:                      /* no concept of TSDUs */
				case -2:                       /* can't send normal data */
					return (FALSE);
					break;
				case -1:                        /* no limit on TSDU size */
					return (TRUE);
					break;
				default:
					if (tinfo.tsdu < xdr_sizeof(xdrfunc, xdrdata))
						return (FALSE);
					else
						return (TRUE);
			}
		} else
			return (TRUE);
	}
}

The second xdr_sizeof() example follows.


Example A–6 xdr_sizeof Example #2

#include <sys/statvfs.h>

#include <sys/sysmacros.h>
 
/*
 *	This function takes as input a file name, an XDR function, and
a
 *	pointer to data to be XDR'd. It returns TRUE if the filesystem
 *	on which the file resides has room for the additional amount
of
 *	data to be XDR'd. Note that since the information statvfs(2)
 *	returns about the filesystem is in blocks you must convert the
 *	value returned by xdr_sizeof() from bytes to disk blocks.
 */
bool_t
canwrite(file, xdrfunc, xdrdata)
	char	     *file;
	xdrproc_t xdrfunc;
	void     *xdrdata;
{
	struct statvfs s;
 
	if (statvfs(file, &s) == -1) {
		/* handle statvfs() error */
		return (FALSE);
	}
 
	if (s.f_bavail >= btod(xdr_sizeof(xdrfunc, xdrdata)))
		return (TRUE);
	else
		return (FALSE);
}