ONC+ Developer's Guide

Compile-Time C-style Mode

Also called Newstyle mode, the -N flag causes rpcgen to produce code in which arguments are passed by value and multiple arguments are passed without a struct. These changes enable RPC code that is more like C and other high-level languages. For compatibility with existing programs and make files, the previous standard mode of argument passing is the default. The following examples demonstrate the new feature. The source modules for both modes, C-style and default, are shown in Example 3–8 and Example 3–9 respectively.


Example 3–8 C-style Mode Version of add.x

/*
 * This program contains a procedure
 * to add 2 numbers. It demonstrates
 * the C-style mode argument passing.
 * Note that add() has 2 arguments.
 */
program ADDPROG {					/* program number */
	version ADDVER {					/* version number */
		int add(int, int) = 1;		/* procedure */
	} = 1;
} = 0x20000199;


Example 3–9 Default Mode Version of add.x

/*
 * This program contains a procedure
 * to add 2 numbers. It demonstrates
 * the "default" mode argument passing.
 * In this mode rpcgen can process
 * only one argument.
 */
struct add_arg {
	int first;
	int second;
};
program ADDPROG {					/* program number */
	version ADDVER {					/* version number */
		int add (add_arg) = 1;		/* procedure */
	} = 1;
} = 0x20000199;

The next four examples show the resulting client-side templates.


Example 3–10 C-style Mode Client Stub for add.x

/*
 * The C-style client side main
 * routine calls the  add() function
 * on the remote rpc server
 */
#include <stdio.h>
#include "add.h"
 
main(argc, argv)
int argc;
char *argv[];
{
	CLIENT *clnt;
	int *result,x,y;
	
	if(argc != 4) {
		printf("usage: %s host num1 
					num2\n" argv[0]);
		exit(1);
	}
	/* create client handle -
 * bind to server
 */
	clnt = clnt_create(argv[1], ADDPROG,
								ADDVER, "udp");
	if (clnt == NULL) {
		clnt_pcreateerror(argv[1]);
		exit(1);
	}
	x = atoi(argv[2]);
	y = atoi(argv[3]);
	/*
	 * invoke remote procedure: Note that
 * multiple arguments can be passed to
	 * add_l() instead of a pointer
	 */
	result = add_1(x, y, clnt);
	if (result == (int *) NULL) {
		clnt_perror(clnt, "call failed:");
		exit(1);
	} else {
		printf("Success: %d + %d = %d\n", 
					x, y, *result);
	}
	exit(0);
}

The following code example shows how the default mode code differs from C-style mode code.


Example 3–11 Default Mode Client

	arg.first = atoi(argv[2]);
	arg.second = atoi(argv[3]);
	/*
	 * invoke remote procedure -- note 
 * that a pointer to the argument has
	 * to be passed to the client stub
	 */
	result = add_1(&arg, clnt);

The server-side procedure in C-style mode is shown in the following example.


Example 3–12 C-style Mode Server

#include "add.h"

int *
add_1(arg1, arg2, rqstp)
	int arg1;
	int arg2;
	struct svc_req *rqstp;
{
	static int result;

	result = arg1 + arg2;
	return(&result);
}

The server-side procedure in default mode is shown in the following code example.


Example 3–13 Default Mode Server Stub

#include "add.h"
int *
add_1(argp, rqstp)
	add_arg *argp;
	struct svc_req *rqstp;
{
	static int result;

	result = argp->first + argp->second;
	return(&result);
}