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 $
9 .if \\n%=1 .tl ''- % -''
12 .\" prevent excess underlining in nroff
14 .OH '\fBrpcgen\fP Programming Guide''Page %'
15 .EH 'Page %''\fBrpcgen\fP Programming Guide'
18 \&\fBrpcgen\fP Programming Guide
20 \&The \fBrpcgen\fP Protocol Compiler
21 .IX rpcgen "" \fIrpcgen\fP "" PAGE MAJOR
23 .IX RPC "" "" \fIrpcgen\fP
24 The details of programming applications to use Remote Procedure Calls
25 can be overwhelming. Perhaps most daunting is the writing of the XDR
26 routines necessary to convert procedure arguments and results into
27 their network format and vice-versa.
31 exists to help programmers write RPC applications simply and directly.
33 does most of the dirty work, allowing programmers to debug
34 the main features of their application, instead of requiring them to
35 spend most of their time debugging their network interface code.
38 is a compiler. It accepts a remote program interface definition written
39 in a language, called RPC Language, which is similar to C. It produces a C
40 language output which includes stub versions of the client routines, a
41 server skeleton, XDR filter routines for both parameters and results, and a
42 header file that contains common definitions. The client stubs interface
43 with the RPC library and effectively hide the network from their callers.
44 The server stub similarly hides the network from the server procedures that
45 are to be invoked by remote clients.
47 output files can be compiled and linked in the usual way. The developer
48 writes server procedures\(emin any language that observes Sun calling
49 conventions\(emand links them with the server skeleton produced by
51 to get an executable server program. To use a remote program, a programmer
52 writes an ordinary main program that makes local procedure calls to the
53 client stubs produced by
55 Linking this program with
57 stubs creates an executable program. (At present the main program must be
60 options can be used to suppress stub generation and to specify the transport
61 to be used by the server stub.
65 reduces development time
66 that would otherwise be spent coding and debugging low-level routines.
67 All compilers, including
69 do this at a small cost in efficiency
70 and flexibility. However, many compilers allow escape hatches for
71 programmers to mix low-level code with high-level code.
73 is no exception. In speed-critical applications, hand-written routines
74 can be linked with the
76 output without any difficulty. Also, one may proceed by using
78 output as a starting point, and then rewriting it as necessary.
79 (If you need a discussion of RPC programming without
82 .I "Remote Procedure Call Programming Guide)\.
84 \&Converting Local Procedures into Remote Procedures
85 .IX rpcgen "local procedures" \fIrpcgen\fP
86 .IX rpcgen "remote procedures" \fIrpcgen\fP
88 Assume an application that runs on a single machine, one which we want
89 to convert to run over the network. Here we will demonstrate such a
90 conversion by way of a simple example\(ema program that prints a
91 message to the console:
96 * printmsg.c: print a message on the console
108 fprintf(stderr, "usage: %s <message>\en", argv[0]);
113 if (!printmessage(message)) {
114 fprintf(stderr, "%s: couldn't print your message\en",
118 printf("Message Delivered!\en");
123 * Print a message to the console.
124 * Return a boolean indicating whether the message was actually printed.
132 f = fopen("/dev/console", "w");
136 fprintf(f, "%s\en", msg);
146 example% \fBcc printmsg.c -o printmsg\fP
147 example% \fBprintmsg "Hello, there."\fP
154 was turned into a remote procedure,
155 then it could be called from anywhere in the network.
156 Ideally, one would just like to stick a keyword like
159 procedure to turn it into a remote procedure. Unfortunately,
160 we have to live within the constraints of the C language, since
161 it existed long before RPC did. But even without language
162 support, it's not very difficult to make a procedure remote.
164 In general, it's necessary to figure out what the types are for
165 all procedure inputs and outputs. In this case, we have a
168 which takes a string as input, and returns an integer
169 as output. Knowing this, we can write a protocol specification in RPC
170 language that describes the remote version of
177 * msg.x: Remote message printing protocol
181 program MESSAGEPROG {
182 version MESSAGEVERS {
183 int PRINTMESSAGE(string) = 1;
188 Remote procedures are part of remote programs, so we actually declared
189 an entire remote program here which contains the single procedure
191 This procedure was declared to be in version 1 of the
192 remote program. No null procedure (procedure 0) is necessary because
194 generates it automatically.
196 Notice that everything is declared with all capital letters. This is
197 not required, but is a good convention to follow.
199 Notice also that the argument type is \*Qstring\*U and not \*Qchar *\*U. This
200 is because a \*Qchar *\*U in C is ambiguous. Programmers usually intend it
201 to mean a null-terminated string of characters, but it could also
202 represent a pointer to a single character or a pointer to an array of
203 characters. In RPC language, a null-terminated string is
204 unambiguously called a \*Qstring\*U.
206 There are just two more things to write. First, there is the remote
207 procedure itself. Here's the definition of a remote procedure
210 procedure we declared above:
216 * msg_proc.c: implementation of the remote procedure "printmessage"
221 #include <rpc/rpc.h> /* \fIalways needed\fP */
222 #include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */
226 * Remote verson of "printmessage"
233 static int result; /* \fImust be static!\fP */
236 f = fopen("/dev/console", "w");
241 fprintf(f, "%s\en", *msg);
249 Notice here that the declaration of the remote procedure
251 differs from that of the local procedure
255 It takes a pointer to a string instead of a string itself. This
256 is true of all remote procedures: they always take pointers to their
257 arguments rather than the arguments themselves.
259 It returns a pointer to an integer instead of an integer itself. This is
260 also generally true of remote procedures: they always return a pointer
263 It has an \*Q_1\*U appended to its name. In general, all remote
266 are named by the following rule: the name in the program definition
270 lower-case letters, an underbar (\*Q_\*U) is appended to it, and
271 finally the version number (here 1) is appended.
273 The last thing to do is declare the main client program that will call
274 the remote procedure. Here it is:
279 * rprintmsg.c: remote version of "printmsg.c"
283 #include <rpc/rpc.h> /* \fIalways needed\fP */
284 #include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */
296 fprintf(stderr, "usage: %s host message\en", argv[0]);
302 * Save values of command line arguments
310 * Create client "handle" used for calling \fIMESSAGEPROG\fP on the
311 * server designated on the command line. We tell the RPC package
312 * to use the "tcp" protocol when contacting the server.
315 cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, "tcp");
319 * Couldn't establish connection with server.
320 * Print error message and die.
323 clnt_pcreateerror(server);
329 * Call the remote procedure "printmessage" on the server
332 result = printmessage_1(&message, cl);
333 if (result == NULL) {
336 * An error occurred while calling the server.
337 * Print error message and die.
340 clnt_perror(cl, server);
346 * Okay, we successfully called the remote procedure.
352 * Server was unable to print our message.
353 * Print error message and die.
356 fprintf(stderr, "%s: %s couldn't print your message\en",
363 * The message got printed on the server's console
366 printf("Message delivered to %s!\en", server);
369 There are two things to note here:
371 .IX "client handle, used by rpcgen" "" "client handle, used by \fIrpcgen\fP"
372 First a client \*Qhandle\*U is created using the RPC library routine
374 This client handle will be passed to the stub routines
375 which call the remote procedure.
379 is called exactly the same way as it is declared in
381 except for the inserted client handle as the first argument.
383 Here's how to put all of the pieces together:
387 example% \fBrpcgen msg.x\fP
388 example% \fBcc rprintmsg.c msg_clnt.c -o rprintmsg\fP
389 example% \fBcc msg_proc.c msg_svc.c -o msg_server\fP
391 Two programs were compiled here: the client program
393 and the server program
395 Before doing this though,
397 was used to fill in the missing pieces.
401 did with the input file
404 It created a header file called
413 for use in the other modules.
415 It created client \*Qstub\*U routines in the
417 file. In this case there is only one, the
419 that was referred to from the
421 client program. The name of the output file for
422 client stub routines is always formed in this way: if the name of the
425 the client stubs output file is called
428 It created the server program which calls
432 This server program is named
434 The rule for naming the server output file is similar to the
435 previous one: for an input file called
437 the output server file is named
440 Now we're ready to have some fun. First, copy the server to a
441 remote machine and run it. For this example, the
442 machine is called \*Qmoon\*U. Server processes are run in the
443 background, because they never exit.
447 moon% \fBmsg_server &\fP
449 Then on our local machine (\*Qsun\*U) we can print a message on \*Qmoon\*Us
454 sun% \fBprintmsg moon "Hello, moon."\fP
456 The message will get printed to \*Qmoon\*Us console. You can print a
457 message on anybody's console (including your own) with this program if
458 you are able to copy the server to their machine and run it.
460 \&Generating XDR Routines
461 .IX RPC "generating XDR routines"
463 The previous example only demonstrated the automatic generation of
464 client and server RPC code.
466 may also be used to generate XDR routines, that is, the routines
467 necessary to convert local data
468 structures into network format and vice-versa. This example presents
469 a complete RPC service\(ema remote directory listing service, which uses
471 not only to generate stub routines, but also to generate the XDR
472 routines. Here is the protocol description file:
477 * dir.x: Remote directory listing protocol
480 const MAXNAMELEN = 255; /* \fImaximum length of a directory entry\fP */
482 typedef string nametype<MAXNAMELEN>; /* \fIa directory entry\fP */
484 typedef struct namenode *namelist; /* \fIa link in the listing\fP */
488 * A node in the directory listing
492 nametype name; /* \fIname of directory entry\fP */
493 namelist next; /* \fInext entry\fP */
498 * The result of a READDIR operation.
501 union readdir_res switch (int errno) {
503 namelist list; /* \fIno error: return directory listing\fP */
505 void; /* \fIerror occurred: nothing else to return\fP */
510 * The directory program definition
516 READDIR(nametype) = 1;
525 in the example above) can be defined using
526 the \*Qstruct\*U, \*Qunion\*U and \*Qenum\*U keywords, but those keywords
527 should not be used in subsequent declarations of variables of those types.
528 For example, if you define a union \*Qfoo\*U, you should declare using
529 only \*Qfoo\*U and not \*Qunion foo\*U. In fact,
532 RPC unions into C structures and it is an error to declare them using the
539 creates four output files. Three are the same as before: header file,
540 client stub routines and server skeleton. The fourth are the XDR routines
541 necessary for converting the data types we declared into XDR format and
542 vice-versa. These are output in the file
545 Here is the implementation of the
553 * dir_proc.c: remote readdir implementation
561 extern char *malloc();
562 extern char *strdup();
572 static readdir_res res; /* \fImust be static\fP! */
579 dirp = opendir(*dirname);
587 * Free previous result
590 xdr_free(xdr_readdir_res, &res);
594 * Collect directory entries.
595 * Memory allocated here will be freed by \fIxdr_free\fP
596 * next time \fIreaddir_1\fP is called
599 nlp = &res.readdir_res_u.list;
600 while (d = readdir(dirp)) {
601 nl = *nlp = (namenode *) malloc(sizeof(namenode));
602 nl->name = strdup(d->d_name);
618 Finally, there is the client side program to call the server:
623 * rls.c: Remote directory listing client
627 #include <rpc/rpc.h> /* \fIalways need this\fP */
628 #include "dir.h" /* \fIwill be generated by rpcgen\fP */
644 fprintf(stderr, "usage: %s host directory\en",
651 * Remember what our command line arguments refer to
659 * Create client "handle" used for calling \fIMESSAGEPROG\fP on the
660 * server designated on the command line. We tell the RPC package
661 * to use the "tcp" protocol when contacting the server.
664 cl = clnt_create(server, DIRPROG, DIRVERS, "tcp");
668 * Couldn't establish connection with server.
669 * Print error message and die.
672 clnt_pcreateerror(server);
678 * Call the remote procedure \fIreaddir\fP on the server
681 result = readdir_1(&dir, cl);
682 if (result == NULL) {
685 * An error occurred while calling the server.
686 * Print error message and die.
689 clnt_perror(cl, server);
695 * Okay, we successfully called the remote procedure.
698 if (result->errno != 0) {
701 * A remote system error occurred.
702 * Print error message and die.
705 errno = result->errno;
712 * Successfully got a directory listing.
716 for (nl = result->readdir_res_u.list; nl != NULL;
718 printf("%s\en", nl->name);
723 Compile everything, and run.
726 sun% \fBrpcgen dir.x\fP
727 sun% \fBcc rls.c dir_clnt.c dir_xdr.c -o rls\fP
728 sun% \fBcc dir_svc.c dir_proc.c dir_xdr.c -o dir_svc\fP
732 moon% \fBrls sun /usr/pub\fP
746 .IX "debugging with rpcgen" "" "debugging with \fIrpcgen\fP"
749 The client program and the server procedure can be tested together
750 as a single program by simply linking them with each other rather
751 than with the client and server stubs. The procedure calls will be
752 executed as ordinary local procedure calls and the program can be
753 debugged with a local debugger such as
755 When the program is working, the client program can be linked to
756 the client stub produced by
758 and the server procedures can be linked to the server stub produced
763 \fIIf you do this, you may want to comment out calls to RPC library
764 routines, and have client-side routines call server routines
769 .IX rpcgen "C-preprocessor" \fIrpcgen\fP
771 The C-preprocessor is run on all input files before they are
772 compiled, so all the preprocessor directives are legal within a \*Q.x\*U
773 file. Four symbols may be defined, depending upon which output file is
774 getting generated. The symbols are:
781 RPC_HDR&for header-file output
782 RPC_XDR&for XDR routine output
783 RPC_SVC&for server-skeleton output
784 RPC_CLNT&for client stub output
789 does a little preprocessing of its own. Any line that
790 begins with a percent sign is passed directly into the output file,
791 without any interpretation of the line. Here is a simple example that
792 demonstrates the preprocessing features.
797 * time.x: Remote time protocol
802 unsigned int TIMEGET(void) = 1;
810 % static int thetime;
817 The '%' feature is not generally recommended, as there is no guarantee
818 that the compiler will stick the output where you intended.
820 \&\fBrpcgen\fP Programming Notes
821 .IX rpcgen "other operations" \fIrpcgen\fP
825 .IX rpcgen "timeout changes" \fIrpcgen\fP
827 RPC sets a default timeout of 25 seconds for RPC calls when
829 is used. This timeout may be changed using
831 Here is a small code fragment to demonstrate use of
837 cl = clnt_create("somehost", SOMEPROG, SOMEVERS, "tcp");
841 tv.tv_sec = 60; /* \fIchange timeout to 1 minute\fP */
843 clnt_control(cl, CLSET_TIMEOUT, &tv);
846 \&Handling Broadcast on the Server Side
848 .IX rpcgen "broadcast RPC" \fIrpcgen\fP
850 When a procedure is known to be called via broadcast RPC,
851 it is usually wise for the server to not reply unless it can provide
852 some useful information to the client. This prevents the network
853 from getting flooded by useless replies.
855 To prevent the server from replying, a remote procedure can
856 return NULL as its result, and the server code generated by
858 will detect this and not send out a reply.
860 Here is an example of a procedure that replies only if it
861 thinks it is an NFS server:
866 char notnull; /* \fIjust here so we can use its address\fP */
868 if (access("/etc/exports", F_OK) < 0) {
869 return (NULL); /* \fIprevent RPC from replying\fP */
873 * return non-null pointer so RPC will send out a reply
876 return ((void *)¬null);
879 Note that if procedure returns type \*Qvoid *\*U, they must return a non-NULL
880 pointer if they want RPC to reply for them.
882 \&Other Information Passed to Server Procedures
884 Server procedures will often want to know more about an RPC call
885 than just its arguments. For example, getting authentication information
886 is important to procedures that want to implement some level of security.
887 This extra information is actually supplied to the server procedure as a
888 second argument. Here is an example to demonstrate its use. What we've
889 done here is rewrite the previous
891 procedure to only allow root users to print a message to the console.
894 printmessage_1(msg, rq)
898 static in result; /* \fIMust be static\fP */
900 struct suthunix_parms *aup;
902 aup = (struct authunix_parms *)rq->rq_clntcred;
903 if (aup->aup_uid != 0) {
910 * Same code as before.
918 .IX rpcgen "RPC Language" \fIrpcgen\fP
920 RPC language is an extension of XDR language. The sole extension is
923 type. For a complete description of the XDR language syntax, see the
924 .I "External Data Representation Standard: Protocol Specification"
925 chapter. For a description of the RPC extensions to the XDR language,
927 .I "Remote Procedure Calls: Protocol Specification"
930 However, XDR language is so close to C that if you know C, you know most
931 of it already. We describe here the syntax of the RPC language,
932 showing a few examples along the way. We also show how the various
933 RPC and XDR type definitions get compiled into C type definitions in
934 the output header file.
939 .IX rpcgen definitions \fIrpcgen\fP
941 An RPC language file consists of a series of definitions.
946 definition ";" definition-list
949 It recognizes five types of definitions.
963 .IX rpcgen structures \fIrpcgen\fP
965 An XDR struct is declared almost exactly like its C counterpart. It
966 looks like the following:
970 "struct" struct-ident "{"
976 declaration ";" declaration-list
978 As an example, here is an XDR structure to a two-dimensional
979 coordinate, and the C structure that it gets compiled into in the
983 struct coord { struct coord {
987 typedef struct coord coord;
989 The output is identical to the input, except for the added
991 at the end of the output. This allows one to use \*Qcoord\*U instead of
992 \*Qstruct coord\*U when declaring items.
996 .IX rpcgen unions \fIrpcgen\fP
998 XDR unions are discriminated unions, and look quite different from C
999 unions. They are more analogous to Pascal variant records than they
1004 "union" union-ident "switch" "(" declaration ")" "{"
1009 "case" value ":" declaration ";"
1010 "default" ":" declaration ";"
1011 "case" value ":" declaration ";" case-list
1013 Here is an example of a type that might be returned as the result of a
1014 \*Qread data\*U operation. If there is no error, return a block of data.
1015 Otherwise, don't return anything.
1018 union read_result switch (int errno) {
1025 It gets compiled into the following:
1028 struct read_result {
1034 typedef struct read_result read_result;
1036 Notice that the union component of the output struct has the name as
1037 the type name, except for the trailing \*Q_u\*U.
1041 .IX rpcgen enumerations \fIrpcgen\fP
1043 XDR enumerations have the same syntax as C enumerations.
1047 "enum" enum-ident "{"
1053 enum-value "," enum-value-list
1057 enum-value-ident "=" value
1059 Here is a short example of an XDR enum, and the C enum that it gets
1063 enum colortype { enum colortype {
1065 GREEN = 1, --> GREEN = 1,
1068 typedef enum colortype colortype;
1073 .IX rpcgen typedef \fIrpcgen\fP
1075 XDR typedefs have the same syntax as C typedefs.
1079 "typedef" declaration
1081 Here is an example that defines a
1084 file name strings that have a maximum length of 255 characters.
1087 typedef string fname_type<255>; --> typedef char *fname_type;
1092 .IX rpcgen constants \fIrpcgen\fP
1094 XDR constants symbolic constants that may be used wherever a
1095 integer constant is used, for example, in array size specifications.
1099 "const" const-ident "=" integer
1101 For example, the following defines a constant
1106 const DOZEN = 12; --> #define DOZEN 12
1111 .IX rpcgen programs \fIrpcgen\fP
1113 RPC programs are declared using the following syntax:
1117 "program" program-ident "{"
1123 version ";" version-list
1126 "version" version-ident "{"
1132 procedure ";" procedure-list
1135 type-ident procedure-ident "(" type-ident ")" "=" value
1137 For example, here is the time protocol, revisited:
1142 * time.x: Get or set the time. Time is represented as number of seconds
1143 * since 0:00, January 1, 1970.
1148 unsigned int TIMEGET(void) = 1;
1149 void TIMESET(unsigned) = 2;
1153 This file compiles into #defines in the output header file:
1165 .IX rpcgen declarations \fIrpcgen\fP
1167 In XDR, there are only four kinds of declarations.
1172 fixed-array-declaration
1173 variable-array-declaration
1176 \fB1) Simple declarations\fP are just like simple C declarations.
1180 type-ident variable-ident
1185 colortype color; --> colortype color;
1187 \fB2) Fixed-length Array Declarations\fP are just like C array declarations:
1190 fixed-array-declaration:
1191 type-ident variable-ident "[" value "]"
1196 colortype palette[8]; --> colortype palette[8];
1198 \fB3) Variable-Length Array Declarations\fP have no explicit syntax
1199 in C, so XDR invents its own using angle-brackets.
1202 variable-array-declaration:
1203 type-ident variable-ident "<" value ">"
1204 type-ident variable-ident "<" ">"
1206 The maximum size is specified between the angle brackets. The size may
1207 be omitted, indicating that the array may be of any size.
1210 int heights<12>; /* \fIat most 12 items\fP */
1211 int widths<>; /* \fIany number of items\fP */
1213 Since variable-length arrays have no explicit syntax in C, these
1214 declarations are actually compiled into \*Qstruct\*Us. For example, the
1215 \*Qheights\*U declaration gets compiled into the following struct:
1219 u_int heights_len; /* \fI# of items in array\fP */
1220 int *heights_val; /* \fIpointer to array\fP */
1223 Note that the number of items in the array is stored in the \*Q_len\*U
1224 component and the pointer to the array is stored in the \*Q_val\*U
1225 component. The first part of each of these component's names is the
1226 same as the name of the declared XDR variable.
1228 \fB4) Pointer Declarations\fP are made in
1229 XDR exactly as they are in C. You can't
1230 really send pointers over the network, but you can use XDR pointers
1231 for sending recursive data types such as lists and trees. The type is
1232 actually called \*Qoptional-data\*U, not \*Qpointer\*U, in XDR language.
1235 pointer-declaration:
1236 type-ident "*" variable-ident
1241 listitem *next; --> listitem *next;
1245 .IX rpcgen "special cases" \fIrpcgen\fP
1247 There are a few exceptions to the rules described above.
1250 C has no built-in boolean type. However, the RPC library does a
1257 Things declared as type
1259 in XDR language are compiled into
1261 in the output header file.
1266 bool married; --> bool_t married;
1269 C has no built-in string type, but instead uses the null-terminated
1270 \*Qchar *\*U convention. In XDR language, strings are declared using the
1271 \*Qstring\*U keyword, and compiled into \*Qchar *\*Us in the output header
1272 file. The maximum size contained in the angle brackets specifies the
1273 maximum number of characters allowed in the strings (not counting the
1275 character). The maximum size may be left off, indicating a string
1276 of arbitrary length.
1281 string name<32>; --> char *name;
1282 string longname<>; --> char *longname;
1285 Opaque data is used in RPC and XDR to describe untyped data, that is,
1286 just sequences of arbitrary bytes. It may be declared either as a
1287 fixed or variable length array.
1291 opaque diskblock[512]; --> char diskblock[512];
1293 opaque filedata<1024>; --> struct {
1299 In a void declaration, the variable is not named. The declaration is
1300 just \*Qvoid\*U and nothing else. Void declarations can only occur in two
1301 places: union definitions and program definitions (as the argument or
1302 result of a remote procedure).