Note that in Example 3-27 proc is declared as type rpcproc_t
. Formerly, RPC programs, versions, procedures, and ports were declared to be of type u_long
. On a 32-bit machine, a u_long
is a four-byte quantity (as is an int
); on a 64-bit system, a u_long
is an eight-byte quantity. The data types rpcprog_t, rpcvers_t
, rpc_proc_t
, and rpcport_t
- introduced in Solaris 7 - should be used whenever possible in declaring RPC programs, versions, procedures, and ports in place of both u_long
and long
. The reason is that these newer types provide backwards compatibility with 32-bit
systems; they're guaranteed to be four-byte quantities no matter which system rpcgen is run on. While rpcgenprograms using u_long
versions of programs, versions, and procedures will still run, they may have different consequences on 32- and 64-bit machines. For that reason it is a good idea to replace them with the appropriate newer data types. In fact, it is a good idea to avoid using long
and u_long
whenever possible (see the note below).
Beginning with Solaris 7, source files created byrpcgen, containing XDR routines, use different inline macros depending on whether the code is to run on a 32- or 64-bit machine - specifically, it uses the IXDR_GET_INT32() and IXDR_PUT_INT32() macros instead of IXDR_GETLONG() and IXDR_PUTLONG(). For example, if the rpcgen source file foo.x contains the following code
struct foo { char c; int i1; int i2; int i3; long l; short s; };the resulting foo_xdr.c file will ensure that the correct inline macro is used:
#if defined(_LP64) || defined(_KERNEL) register int *buf; #else register long *buf; #endif . . . #if defined(_LP64) || defined(_KERNEL) IXDR_PUT_INT32(buf, objp->i1); IXDR_PUT_INT32(buf, objp->i2); IXDR_PUT_INT32(buf, objp->i3); IXDR_PUT_INT32(buf, objp->l); IXDR_PUT_SHORT(buf, objp->s); #else IXDR_PUT_LONG(buf, objp->i1); IXDR_PUT_LONG(buf, objp->i2); IXDR_PUT_LONG(buf, objp->i3); IXDR_PUT_LONG(buf, objp->l); IXDR_PUT_SHORT(buf, objp->s); #endifNote that the code declares buf to be either
int
or long
, depending on whether the machine is 64- or 32-bit.
Currently, data types transported via RPC are limited in size to four-byte quantities (32 bits). The eight-byte long
is provided to allow applications to make maximum use of 64-bit architecture. However, programmers should avoid using long
s, and functions that use long
s, such as x_putlong(), in favor of int
s whenever possible. (As noted above, RPC programs, versions, procedures, and ports have their own dedicated types.) The reason is that xdr_long() will fail if the data value is not between INT32_MIN and INT32_MAX - or the data could be truncated if inline macros such as IXDR_GET_LONG() and IXDR_PUT_LONG() are
used. (The same applies for u_long
s.) See also the xdr_long(3NSL) man page.