Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
3.  rpcgen Programming Guide rpcgen Tutorial Passing Complex Data Structures  Previous   Contents   Next 
   
 

The following code example shows the client-side implementation of the READDIR procedure.


Example 3-6 Client-side Implementation of rls.c

/*
 * rls.c: Remote directory listing client
 */
 
#include <stdio.h>
#include "dir.h"                       /* generated by rpcgen */
 
extern int errno;
 
main(argc, argv)
	int argc;
	char *argv[];
{
	CLIENT *clnt;
	char *server;
	char *dir;
	readdir_res *result;
	namelist nl;
 	if (argc != 3) {
		fprintf(stderr, "usage: %s host 
					directory\n",argv[0]);
		exit(1);
	}
	server = argv[1];
	dir = argv[2];
	/*
	 * Create client "handle" used for
 * calling MESSAGEPROG on the server
 * designated on the command line.
	 */
	cl = clnt_create(server, DIRPROG,
								DIRVERS, "tcp");
	if (clnt == (CLIENT *)NULL) {
		clnt_pcreateerror(server);
		exit(1);
	}
	result = readdir_1(&dir, clnt);
	if (result == (readdir_res *)NULL) {
		clnt_perror(clnt, server);
		exit(1);
	}
	/* Okay, we successfully called
 * the remote procedure.
 */
	if (result->errno != 0) {
		/* Remote system error. Print
    * error message and die.
    */
		errno = result->errno;
		perror(dir);
		exit(1);
	}
	/* Successfully got a directory listing.
 * Print it.
 */
	for (nl = result->readdir_res_u.list;
								nl != NULL;
		nl = nl->next) {
		printf("%s\n", nl->name);
	}
	xdr_free(xdr_readdir_res, result);
	clnt_destroy(cl);
	exit(0);}

As in other examples, execution is on systems named local and remote. The files are compiled and run as follows:

 remote$ rpcgen dir.x
 remote$ cc -c dir_xdr.c
 remote$ cc rls.c dir_clnt.c dir_xdr.o -o rls -lnsl
 remote$ cc dir_svc.c dir_proc.c dir_xdr.o -o dir_svc -lnsl
 remote$ dir_svc

When you install rls() on system local, you can list the contents of /usr/share/lib on system remote as follows:

 local$ rls remote /usr/share/lib
 ascii
 eqnchar
 greek
 kbd
 marg8
 tabclr
 tabs
 tabs4
 local
$

Client code generated by rpcgen does not release the memory allocated for the results of the RPC call. Call xdr_free() to release the memory when you are finished with it. Calling xdr_free() is similar to calling the free() routine, except that you pass the XDR routine for the result. In this example, after printing the list, xdr_free(xdr_readdir_res, result); was called.


Note - Use xdr_free() to release memory allocated by malloc(). Failure to use xdr_free() to release memory results in memory leaks.


Preprocessing Directives

rpcgen supports C and other preprocessing features. C preprocessing is performed on rpcgen input files before they are compiled. All standard C preprocessing directives are allowed in the.x source files. Depending on the type of output file being generated, five symbols are defined by rpcgen.

rpcgen provides an additional preprocessing feature: any line that begins with a percent sign (%) is passed directly to the output file, with no action on the line's content. Use caution because rpcgen does not always place the lines where you intend. Check the output source file and, if needed, edit it.

rpcgen uses the preprocessing directives listed in the following table.

Table 3-1 rpcgen Preprocessing Directives

Symbol

Use

RPC_HDR

Header file output

RPC_XDR

XDR routine output

RPC_SVC

Server stub output

RPC_CLNT

Client stub output

RPC_TBL

Index table output

The following code example is a simple rpcgen example. Note the use of rpcgen`s pre-processing features.


Example 3-7 Time Protocol rpcgen Source

/*
 * time.x: Remote time protocol
 */
program TIMEPROG {
	version TIMEVERS {
			unsigned int TIMEGET() = 1;
	} = 1;
} = 0x20000044;

#ifdef RPC_SVC
%int *
%timeget_1()
%{
%	static int thetime;
%
%	thetime = time(0);
%	return (&thetime);
%}
#endif

 
 
 
  Previous   Contents   Next