From: VMware, Inc <> Date: Thu, 17 Dec 2009 22:51:24 +0000 (-0800) Subject: DynXdr: Implement xdr_inline operation. X-Git-Tag: 2009.12.16-217847~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8609338ceeb6c16c993f2f0ba4d76fb9170c1b09;p=thirdparty%2Fopen-vm-tools.git DynXdr: Implement xdr_inline operation. While working with SIGAR => XDR serialization, I ran into segfaults when the rpcgen-generated code called xdr_inline, an operation which we didn't implement. This change fixes that. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/dynxdr/dynxdr.c b/open-vm-tools/lib/dynxdr/dynxdr.c index 792eb4861..bfaab8073 100644 --- a/open-vm-tools/lib/dynxdr/dynxdr.c +++ b/open-vm-tools/lib/dynxdr/dynxdr.c @@ -78,6 +78,14 @@ typedef struct DynXdrData { # define DYNXDR_LONG long #endif +#if defined(sun) +# define DYNXDR_INLINE_T rpc_inline_t +# define DYNXDR_INLINE_LEN_T int +#else +# define DYNXDR_INLINE_T int32_t +# define DYNXDR_INLINE_LEN_T u_int +#endif + /* *----------------------------------------------------------------------------- @@ -200,6 +208,53 @@ DynXdrPutLong(XDR *xdrs, // IN/OUT } +/* + *----------------------------------------------------------------------------- + * + * DynXdrInline -- + * + * Return a pointer to a contiguous buffer of len bytes. On XDR_ENCODE, + * is used to preallocate chunks of the backing buffer such that the caller + * may set bulk 4-byte members w/o reallocating each time. + * + * Results: + * Valid pointer on success, NULL on failure. + * + * Side effects: + * Backing DynBuf may be enlarged. + * + *----------------------------------------------------------------------------- + */ + +static DYNXDR_INLINE_T * +DynXdrInline(XDR *xdrs, // IN/OUT + DYNXDR_INLINE_LEN_T len) // IN +{ + DynXdrData *priv = (DynXdrData *)xdrs->x_private; + DynBuf *buf = &priv->data; + DYNXDR_INLINE_T *retAddr; + + ASSERT(len >= 0); + ASSERT(xdrs->x_op == XDR_ENCODE); + + if (len == 0) { + return (DYNXDR_INLINE_T *)&buf->data[buf->size]; + } + + if (buf->allocated - buf->size < len) { + /* DynBuf too small. Grow it. */ + if (!DynBuf_Enlarge(buf, buf->size + len)) { + return NULL; + } + } + + retAddr = (DYNXDR_INLINE_T *)&buf->data[buf->size]; + buf->size += len; + + return retAddr; +} + + /* *----------------------------------------------------------------------------- * @@ -234,7 +289,7 @@ DynXdr_Create(XDR *in) // IN DynXdrPutBytes, /* x_putbytes */ DynXdrGetPos, /* x_getpostn */ NULL, /* x_setpostn */ - NULL, /* x_inline */ + DynXdrInline, /* x_inline */ NULL, /* x_destroy */ #if defined(__GLIBC__) NULL, /* x_getint32 */