2 .\" Must use -- tbl -- for this one
4 .\" @(#)rpcgen.ms 2.2 88/08/04 4.0 RPCSRC
5 .\" $FreeBSD: src/lib/libc/rpc/PSD.doc/rpcgen.ms,v 1.1.14.1 2000/11/24 09:36:30 ru Exp $
6 .\" $DragonFly: src/lib/libc/rpc/PSD.doc/rpcgen.ms,v 1.2 2003/06/17 04:26:45 dillon Exp $
10 .if \\n%=1 .tl ''- % -''
13 .\" prevent excess underlining in nroff
15 .OH '\fBrpcgen\fP Programming Guide''Page %'
16 .EH 'Page %''\fBrpcgen\fP Programming Guide'
19 \&\fBrpcgen\fP Programming Guide
21 \&The \fBrpcgen\fP Protocol Compiler
22 .IX rpcgen "" \fIrpcgen\fP "" PAGE MAJOR
24 .IX RPC "" "" \fIrpcgen\fP
25 The details of programming applications to use Remote Procedure Calls
26 can be overwhelming. Perhaps most daunting is the writing of the XDR
27 routines necessary to convert procedure arguments and results into
28 their network format and vice-versa.
32 exists to help programmers write RPC applications simply and directly.
34 does most of the dirty work, allowing programmers to debug
35 the main features of their application, instead of requiring them to
36 spend most of their time debugging their network interface code.
39 is a compiler. It accepts a remote program interface definition written
40 in a language, called RPC Language, which is similar to C. It produces a C
41 language output which includes stub versions of the client routines, a
42 server skeleton, XDR filter routines for both parameters and results, and a
43 header file that contains common definitions. The client stubs interface
44 with the RPC library and effectively hide the network from their callers.
45 The server stub similarly hides the network from the server procedures that
46 are to be invoked by remote clients.
48 output files can be compiled and linked in the usual way. The developer
49 writes server procedures\(emin any language that observes Sun calling
50 conventions\(emand links them with the server skeleton produced by
52 to get an executable server program. To use a remote program, a programmer
53 writes an ordinary main program that makes local procedure calls to the
54 client stubs produced by
56 Linking this program with
58 stubs creates an executable program. (At present the main program must be
61 options can be used to suppress stub generation and to specify the transport
62 to be used by the server stub.
66 reduces development time
67 that would otherwise be spent coding and debugging low-level routines.
68 All compilers, including
70 do this at a small cost in efficiency
71 and flexibility. However, many compilers allow escape hatches for
72 programmers to mix low-level code with high-level code.
74 is no exception. In speed-critical applications, hand-written routines
75 can be linked with the
77 output without any difficulty. Also, one may proceed by using
79 output as a starting point, and then rewriting it as necessary.
80 (If you need a discussion of RPC programming without
83 .I "Remote Procedure Call Programming Guide)\.
85 \&Converting Local Procedures into Remote Procedures
86 .IX rpcgen "local procedures" \fIrpcgen\fP
87 .IX rpcgen "remote procedures" \fIrpcgen\fP
89 Assume an application that runs on a single machine, one which we want
90 to convert to run over the network. Here we will demonstrate such a
91 conversion by way of a simple example\(ema program that prints a
92 message to the console:
97 * printmsg.c: print a message on the console
109 fprintf(stderr, "usage: %s <message>\en", argv[0]);
114 if (!printmessage(message)) {
115 fprintf(stderr, "%s: couldn't print your message\en",
119 printf("Message Delivered!\en");
124 * Print a message to the console.
125 * Return a boolean indicating whether the message was actually printed.
133 f = fopen("/dev/console", "w");
137 fprintf(f, "%s\en", msg);
147 example% \fBcc printmsg.c -o printmsg\fP
148 example% \fBprintmsg "Hello, there."\fP
155 was turned into a remote procedure,
156 then it could be called from anywhere in the network.
157 Ideally, one would just like to stick a keyword like
160 procedure to turn it into a remote procedure. Unfortunately,
161 we have to live within the constraints of the C language, since
162 it existed long before RPC did. But even without language
163 support, it's not very difficult to make a procedure remote.
165 In general, it's necessary to figure out what the types are for
166 all procedure inputs and outputs. In this case, we have a
169 which takes a string as input, and returns an integer
170 as output. Knowing this, we can write a protocol specification in RPC
171 language that describes the remote version of
178 * msg.x: Remote message printing protocol
182 program MESSAGEPROG {
183 version MESSAGEVERS {
184 int PRINTMESSAGE(string) = 1;
189 Remote procedures are part of remote programs, so we actually declared
190 an entire remote program here which contains the single procedure
192 This procedure was declared to be in version 1 of the
193 remote program. No null procedure (procedure 0) is necessary because
195 generates it automatically.
197 Notice that everything is declared with all capital letters. This is
198 not required, but is a good convention to follow.
200 Notice also that the argument type is \*Qstring\*U and not \*Qchar *\*U. This
201 is because a \*Qchar *\*U in C is ambiguous. Programmers usually intend it
202 to mean a null-terminated string of characters, but it could also
203 represent a pointer to a single character or a pointer to an array of
204 characters. In RPC language, a null-terminated string is
205 unambiguously called a \*Qstring\*U.
207 There are just two more things to write. First, there is the remote
208 procedure itself. Here's the definition of a remote procedure
211 procedure we declared above:
217 * msg_proc.c: implementation of the remote procedure "printmessage"
222 #include <rpc/rpc.h> /* \fIalways needed\fP */
223 #include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */
227 * Remote verson of "printmessage"
234 static int result; /* \fImust be static!\fP */
237 f = fopen("/dev/console", "w");
242 fprintf(f, "%s\en", *msg);
250 Notice here that the declaration of the remote procedure
252 differs from that of the local procedure
256 It takes a pointer to a string instead of a string itself. This
257 is true of all remote procedures: they always take pointers to their
258 arguments rather than the arguments themselves.
260 It returns a pointer to an integer instead of an integer itself. This is
261 also generally true of remote procedures: they always return a pointer
264 It has an \*Q_1\*U appended to its name. In general, all remote
267 are named by the following rule: the name in the program definition
271 lower-case letters, an underbar (\*Q_\*U) is appended to it, and
272 finally the version number (here 1) is appended.
274 The last thing to do is declare the main client program that will call
275 the remote procedure. Here it is:
280 * rprintmsg.c: remote version of "printmsg.c"
284 #include <rpc/rpc.h> /* \fIalways needed\fP */
285 #include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */
297 fprintf(stderr, "usage: %s host message\en", argv[0]);
303 * Save values of command line arguments
311 * Create client "handle" used for calling \fIMESSAGEPROG\fP on the
312 * server designated on the command line. We tell the RPC package
313 * to use the "tcp" protocol when contacting the server.
316 cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, "tcp");
320 * Couldn't establish connection with server.
321 * Print error message and die.
324 clnt_pcreateerror(server);
330 * Call the remote procedure "printmessage" on the server
333 result = printmessage_1(&message, cl);
334 if (result == NULL) {
337 * An error occurred while calling the server.
338 * Print error message and die.
341 clnt_perror(cl, server);
347 * Okay, we successfully called the remote procedure.
353 * Server was unable to print our message.
354 * Print error message and die.
357 fprintf(stderr, "%s: %s couldn't print your message\en",
364 * The message got printed on the server's console
367 printf("Message delivered to %s!\en", server);
370 There are two things to note here:
372 .IX "client handle, used by rpcgen" "" "client handle, used by \fIrpcgen\fP"
373 First a client \*Qhandle\*U is created using the RPC library routine
375 This client handle will be passed to the stub routines
376 which call the remote procedure.
380 is called exactly the same way as it is declared in
382 except for the inserted client handle as the first argument.
384 Here's how to put all of the pieces together:
388 example% \fBrpcgen msg.x\fP
389 example% \fBcc rprintmsg.c msg_clnt.c -o rprintmsg\fP
390 example% \fBcc msg_proc.c msg_svc.c -o msg_server\fP
392 Two programs were compiled here: the client program
394 and the server program
396 Before doing this though,
398 was used to fill in the missing pieces.
402 did with the input file
405 It created a header file called
414 for use in the other modules.
416 It created client \*Qstub\*U routines in the
418 file. In this case there is only one, the
420 that was referred to from the
422 client program. The name of the output file for
423 client stub routines is always formed in this way: if the name of the
426 the client stubs output file is called
429 It created the server program which calls
433 This server program is named
435 The rule for naming the server output file is similar to the
436 previous one: for an input file called
438 the output server file is named
441 Now we're ready to have some fun. First, copy the server to a
442 remote machine and run it. For this example, the
443 machine is called \*Qmoon\*U. Server processes are run in the
444 background, because they never exit.
448 moon% \fBmsg_server &\fP
450 Then on our local machine (\*Qsun\*U) we can print a message on \*Qmoon\*Us
455 sun% \fBprintmsg moon "Hello, moon."\fP
457 The message will get printed to \*Qmoon\*Us console. You can print a
458 message on anybody's console (including your own) with this program if
459 you are able to copy the server to their machine and run it.
461 \&Generating XDR Routines
462 .IX RPC "generating XDR routines"
464 The previous example only demonstrated the automatic generation of
465 client and server RPC code.
467 may also be used to generate XDR routines, that is, the routines
468 necessary to convert local data
469 structures into network format and vice-versa. This example presents
470 a complete RPC service\(ema remote directory listing service, which uses
472 not only to generate stub routines, but also to generate the XDR
473 routines. Here is the protocol description file:
478 * dir.x: Remote directory listing protocol
481 const MAXNAMELEN = 255; /* \fImaximum length of a directory entry\fP */
483 typedef string nametype<MAXNAMELEN>; /* \fIa directory entry\fP */
485 typedef struct namenode *namelist; /* \fIa link in the listing\fP */
489 * A node in the directory listing
493 nametype name; /* \fIname of directory entry\fP */
494 namelist next; /* \fInext entry\fP */
499 * The result of a READDIR operation.
502 union readdir_res switch (int errno) {
504 namelist list; /* \fIno error: return directory listing\fP */
506 void; /* \fIerror occurred: nothing else to return\fP */
511 * The directory program definition
517 READDIR(nametype) = 1;
526 in the example above) can be defined using
527 the \*Qstruct\*U, \*Qunion\*U and \*Qenum\*U keywords, but those keywords
528 should not be used in subsequent declarations of variables of those types.
529 For example, if you define a union \*Qfoo\*U, you should declare using
530 only \*Qfoo\*U and not \*Qunion foo\*U. In fact,
533 RPC unions into C structures and it is an error to declare them using the
540 creates four output files. Three are the same as before: header file,
541 client stub routines and server skeleton. The fourth are the XDR routines
542 necessary for converting the data types we declared into XDR format and
543 vice-versa. These are output in the file
546 Here is the implementation of the
554 * dir_proc.c: remote readdir implementation
562 extern char *malloc();
563 extern char *strdup();
573 static readdir_res res; /* \fImust be static\fP! */
580 dirp = opendir(*dirname);
588 * Free previous result
591 xdr_free(xdr_readdir_res, &res);
595 * Collect directory entries.
596 * Memory allocated here will be freed by \fIxdr_free\fP
597 * next time \fIreaddir_1\fP is called
600 nlp = &res.readdir_res_u.list;
601 while (d = readdir(dirp)) {
602 nl = *nlp = (namenode *) malloc(sizeof(namenode));
603 nl->name = strdup(d->d_name);
619 Finally, there is the client side program to call the server:
624 * rls.c: Remote directory listing client
628 #include <rpc/rpc.h> /* \fIalways need this\fP */
629 #include "dir.h" /* \fIwill be generated by rpcgen\fP */
645 fprintf(stderr, "usage: %s host directory\en",
652 * Remember what our command line arguments refer to
660 * Create client "handle" used for calling \fIMESSAGEPROG\fP on the
661 * server designated on the command line. We tell the RPC package
662 * to use the "tcp" protocol when contacting the server.
665 cl = clnt_create(server, DIRPROG, DIRVERS, "tcp");
669 * Couldn't establish connection with server.
670 * Print error message and die.
673 clnt_pcreateerror(server);
679 * Call the remote procedure \fIreaddir\fP on the server
682 result = readdir_1(&dir, cl);
683 if (result == NULL) {
686 * An error occurred while calling the server.
687 * Print error message and die.
690 clnt_perror(cl, server);
696 * Okay, we successfully called the remote procedure.
699 if (result->errno != 0) {
702 * A remote system error occurred.
703 * Print error message and die.
706 errno = result->errno;
713 * Successfully got a directory listing.
717 for (nl = result->readdir_res_u.list; nl != NULL;
719 printf("%s\en", nl->name);
724 Compile everything, and run.
727 sun% \fBrpcgen dir.x\fP
728 sun% \fBcc rls.c dir_clnt.c dir_xdr.c -o rls\fP
729 sun% \fBcc dir_svc.c dir_proc.c dir_xdr.c -o dir_svc\fP
733 moon% \fBrls sun /usr/pub\fP
747 .IX "debugging with rpcgen" "" "debugging with \fIrpcgen\fP"
750 The client program and the server procedure can be tested together
751 as a single program by simply linking them with each other rather
752 than with the client and server stubs. The procedure calls will be
753 executed as ordinary local procedure calls and the program can be
754 debugged with a local debugger such as
756 When the program is working, the client program can be linked to
757 the client stub produced by
759 and the server procedures can be linked to the server stub produced
764 \fIIf you do this, you may want to comment out calls to RPC library
765 routines, and have client-side routines call server routines
770 .IX rpcgen "C-preprocessor" \fIrpcgen\fP
772 The C-preprocessor is run on all input files before they are
773 compiled, so all the preprocessor directives are legal within a \*Q.x\*U
774 file. Four symbols may be defined, depending upon which output file is
775 getting generated. The symbols are:
782 RPC_HDR&for header-file output
783 RPC_XDR&for XDR routine output
784 RPC_SVC&for server-skeleton output
785 RPC_CLNT&for client stub output
790 does a little preprocessing of its own. Any line that
791 begins with a percent sign is passed directly into the output file,
792 without any interpretation of the line. Here is a simple example that
793 demonstrates the preprocessing features.
798 * time.x: Remote time protocol
803 unsigned int TIMEGET(void) = 1;
811 % static int thetime;
818 The '%' feature is not generally recommended, as there is no guarantee
819 that the compiler will stick the output where you intended.
821 \&\fBrpcgen\fP Programming Notes
822 .IX rpcgen "other operations" \fIrpcgen\fP
826 .IX rpcgen "timeout changes" \fIrpcgen\fP
828 RPC sets a default timeout of 25 seconds for RPC calls when
830 is used. This timeout may be changed using
832 Here is a small code fragment to demonstrate use of
838 cl = clnt_create("somehost", SOMEPROG, SOMEVERS, "tcp");
842 tv.tv_sec = 60; /* \fIchange timeout to 1 minute\fP */
844 clnt_control(cl, CLSET_TIMEOUT, &tv);
847 \&Handling Broadcast on the Server Side
849 .IX rpcgen "broadcast RPC" \fIrpcgen\fP
851 When a procedure is known to be called via broadcast RPC,
852 it is usually wise for the server to not reply unless it can provide
853 some useful information to the client. This prevents the network
854 from getting flooded by useless replies.
856 To prevent the server from replying, a remote procedure can
857 return NULL as its result, and the server code generated by
859 will detect this and not send out a reply.
861 Here is an example of a procedure that replies only if it
862 thinks it is an NFS server:
867 char notnull; /* \fIjust here so we can use its address\fP */
869 if (access("/etc/exports", F_OK) < 0) {
870 return (NULL); /* \fIprevent RPC from replying\fP */
874 * return non-null pointer so RPC will send out a reply
877 return ((void *)¬null);
880 Note that if procedure returns type \*Qvoid *\*U, they must return a non-NULL
881 pointer if they want RPC to reply for them.
883 \&Other Information Passed to Server Procedures
885 Server procedures will often want to know more about an RPC call
886 than just its arguments. For example, getting authentication information
887 is important to procedures that want to implement some level of security.
888 This extra information is actually supplied to the server procedure as a
889 second argument. Here is an example to demonstrate its use. What we've
890 done here is rewrite the previous
892 procedure to only allow root users to print a message to the console.
895 printmessage_1(msg, rq)
899 static in result; /* \fIMust be static\fP */
901 struct suthunix_parms *aup;
903 aup = (struct authunix_parms *)rq->rq_clntcred;
904 if (aup->aup_uid != 0) {
911 * Same code as before.
919 .IX rpcgen "RPC Language" \fIrpcgen\fP
921 RPC language is an extension of XDR language. The sole extension is
924 type. For a complete description of the XDR language syntax, see the
925 .I "External Data Representation Standard: Protocol Specification"
926 chapter. For a description of the RPC extensions to the XDR language,
928 .I "Remote Procedure Calls: Protocol Specification"
931 However, XDR language is so close to C that if you know C, you know most
932 of it already. We describe here the syntax of the RPC language,
933 showing a few examples along the way. We also show how the various
934 RPC and XDR type definitions get compiled into C type definitions in
935 the output header file.
940 .IX rpcgen definitions \fIrpcgen\fP
942 An RPC language file consists of a series of definitions.
947 definition ";" definition-list
950 It recognizes five types of definitions.
964 .IX rpcgen structures \fIrpcgen\fP
966 An XDR struct is declared almost exactly like its C counterpart. It
967 looks like the following:
971 "struct" struct-ident "{"
977 declaration ";" declaration-list
979 As an example, here is an XDR structure to a two-dimensional
980 coordinate, and the C structure that it gets compiled into in the
984 struct coord { struct coord {
988 typedef struct coord coord;
990 The output is identical to the input, except for the added
992 at the end of the output. This allows one to use \*Qcoord\*U instead of
993 \*Qstruct coord\*U when declaring items.
997 .IX rpcgen unions \fIrpcgen\fP
999 XDR unions are discriminated unions, and look quite different from C
1000 unions. They are more analogous to Pascal variant records than they
1005 "union" union-ident "switch" "(" declaration ")" "{"
1010 "case" value ":" declaration ";"
1011 "default" ":" declaration ";"
1012 "case" value ":" declaration ";" case-list
1014 Here is an example of a type that might be returned as the result of a
1015 \*Qread data\*U operation. If there is no error, return a block of data.
1016 Otherwise, don't return anything.
1019 union read_result switch (int errno) {
1026 It gets compiled into the following:
1029 struct read_result {
1035 typedef struct read_result read_result;
1037 Notice that the union component of the output struct has the name as
1038 the type name, except for the trailing \*Q_u\*U.
1042 .IX rpcgen enumerations \fIrpcgen\fP
1044 XDR enumerations have the same syntax as C enumerations.
1048 "enum" enum-ident "{"
1054 enum-value "," enum-value-list
1058 enum-value-ident "=" value
1060 Here is a short example of an XDR enum, and the C enum that it gets
1064 enum colortype { enum colortype {
1066 GREEN = 1, --> GREEN = 1,
1069 typedef enum colortype colortype;
1074 .IX rpcgen typedef \fIrpcgen\fP
1076 XDR typedefs have the same syntax as C typedefs.
1080 "typedef" declaration
1082 Here is an example that defines a
1085 file name strings that have a maximum length of 255 characters.
1088 typedef string fname_type<255>; --> typedef char *fname_type;
1093 .IX rpcgen constants \fIrpcgen\fP
1095 XDR constants symbolic constants that may be used wherever a
1096 integer constant is used, for example, in array size specifications.
1100 "const" const-ident "=" integer
1102 For example, the following defines a constant
1107 const DOZEN = 12; --> #define DOZEN 12
1112 .IX rpcgen programs \fIrpcgen\fP
1114 RPC programs are declared using the following syntax:
1118 "program" program-ident "{"
1124 version ";" version-list
1127 "version" version-ident "{"
1133 procedure ";" procedure-list
1136 type-ident procedure-ident "(" type-ident ")" "=" value
1138 For example, here is the time protocol, revisited:
1143 * time.x: Get or set the time. Time is represented as number of seconds
1144 * since 0:00, January 1, 1970.
1149 unsigned int TIMEGET(void) = 1;
1150 void TIMESET(unsigned) = 2;
1154 This file compiles into #defines in the output header file:
1166 .IX rpcgen declarations \fIrpcgen\fP
1168 In XDR, there are only four kinds of declarations.
1173 fixed-array-declaration
1174 variable-array-declaration
1177 \fB1) Simple declarations\fP are just like simple C declarations.
1181 type-ident variable-ident
1186 colortype color; --> colortype color;
1188 \fB2) Fixed-length Array Declarations\fP are just like C array declarations:
1191 fixed-array-declaration:
1192 type-ident variable-ident "[" value "]"
1197 colortype palette[8]; --> colortype palette[8];
1199 \fB3) Variable-Length Array Declarations\fP have no explicit syntax
1200 in C, so XDR invents its own using angle-brackets.
1203 variable-array-declaration:
1204 type-ident variable-ident "<" value ">"
1205 type-ident variable-ident "<" ">"
1207 The maximum size is specified between the angle brackets. The size may
1208 be omitted, indicating that the array may be of any size.
1211 int heights<12>; /* \fIat most 12 items\fP */
1212 int widths<>; /* \fIany number of items\fP */
1214 Since variable-length arrays have no explicit syntax in C, these
1215 declarations are actually compiled into \*Qstruct\*Us. For example, the
1216 \*Qheights\*U declaration gets compiled into the following struct:
1220 u_int heights_len; /* \fI# of items in array\fP */
1221 int *heights_val; /* \fIpointer to array\fP */
1224 Note that the number of items in the array is stored in the \*Q_len\*U
1225 component and the pointer to the array is stored in the \*Q_val\*U
1226 component. The first part of each of these component's names is the
1227 same as the name of the declared XDR variable.
1229 \fB4) Pointer Declarations\fP are made in
1230 XDR exactly as they are in C. You can't
1231 really send pointers over the network, but you can use XDR pointers
1232 for sending recursive data types such as lists and trees. The type is
1233 actually called \*Qoptional-data\*U, not \*Qpointer\*U, in XDR language.
1236 pointer-declaration:
1237 type-ident "*" variable-ident
1242 listitem *next; --> listitem *next;
1246 .IX rpcgen "special cases" \fIrpcgen\fP
1248 There are a few exceptions to the rules described above.
1251 C has no built-in boolean type. However, the RPC library does a
1258 Things declared as type
1260 in XDR language are compiled into
1262 in the output header file.
1267 bool married; --> bool_t married;
1270 C has no built-in string type, but instead uses the null-terminated
1271 \*Qchar *\*U convention. In XDR language, strings are declared using the
1272 \*Qstring\*U keyword, and compiled into \*Qchar *\*Us in the output header
1273 file. The maximum size contained in the angle brackets specifies the
1274 maximum number of characters allowed in the strings (not counting the
1276 character). The maximum size may be left off, indicating a string
1277 of arbitrary length.
1282 string name<32>; --> char *name;
1283 string longname<>; --> char *longname;
1286 Opaque data is used in RPC and XDR to describe untyped data, that is,
1287 just sequences of arbitrary bytes. It may be declared either as a
1288 fixed or variable length array.
1292 opaque diskblock[512]; --> char diskblock[512];
1294 opaque filedata<1024>; --> struct {
1300 In a void declaration, the variable is not named. The declaration is
1301 just \*Qvoid\*U and nothing else. Void declarations can only occur in two
1302 places: union definitions and program definitions (as the argument or
1303 result of a remote procedure).