2 .\" Must use -- tbl -- for this one
4 .\" @(#)rpcgen.ms 2.2 88/08/04 4.0 RPCSRC
8 .if \\n%=1 .tl ''- % -''
11 .\" prevent excess underlining in nroff
13 .OH '\fBrpcgen\fP Programming Guide''Page %'
14 .EH 'Page %''\fBrpcgen\fP Programming Guide'
17 \&\fBrpcgen\fP Programming Guide
19 \&The \fBrpcgen\fP Protocol Compiler
20 .IX rpcgen "" \fIrpcgen\fP "" PAGE MAJOR
22 .IX RPC "" "" \fIrpcgen\fP
23 The details of programming applications to use Remote Procedure Calls
24 can be overwhelming. Perhaps most daunting is the writing of the XDR
25 routines necessary to convert procedure arguments and results into
26 their network format and vice-versa.
30 exists to help programmers write RPC applications simply and directly.
32 does most of the dirty work, allowing programmers to debug
33 the main features of their application, instead of requiring them to
34 spend most of their time debugging their network interface code.
37 is a compiler. It accepts a remote program interface definition written
38 in a language, called RPC Language, which is similar to C. It produces a C
39 language output which includes stub versions of the client routines, a
40 server skeleton, XDR filter routines for both parameters and results, and a
41 header file that contains common definitions. The client stubs interface
42 with the RPC library and effectively hide the network from their callers.
43 The server stub similarly hides the network from the server procedures that
44 are to be invoked by remote clients.
46 output files can be compiled and linked in the usual way. The developer
47 writes server procedures\(emin any language that observes Sun calling
48 conventions\(emand links them with the server skeleton produced by
50 to get an executable server program. To use a remote program, a programmer
51 writes an ordinary main program that makes local procedure calls to the
52 client stubs produced by
54 Linking this program with
56 stubs creates an executable program. (At present the main program must be
59 options can be used to suppress stub generation and to specify the transport
60 to be used by the server stub.
64 reduces development time
65 that would otherwise be spent coding and debugging low-level routines.
66 All compilers, including
68 do this at a small cost in efficiency
69 and flexibility. However, many compilers allow escape hatches for
70 programmers to mix low-level code with high-level code.
72 is no exception. In speed-critical applications, hand-written routines
73 can be linked with the
75 output without any difficulty. Also, one may proceed by using
77 output as a starting point, and then rewriting it as necessary.
78 (If you need a discussion of RPC programming without
81 .I "Remote Procedure Call Programming Guide)\.
83 \&Converting Local Procedures into Remote Procedures
84 .IX rpcgen "local procedures" \fIrpcgen\fP
85 .IX rpcgen "remote procedures" \fIrpcgen\fP
87 Assume an application that runs on a single machine, one which we want
88 to convert to run over the network. Here we will demonstrate such a
89 conversion by way of a simple example\(ema program that prints a
90 message to the console:
95 * printmsg.c: print a message on the console
107 fprintf(stderr, "usage: %s <message>\en", argv[0]);
112 if (!printmessage(message)) {
113 fprintf(stderr, "%s: couldn't print your message\en",
117 printf("Message Delivered!\en");
122 * Print a message to the console.
123 * Return a boolean indicating whether the message was actually printed.
131 f = fopen("/dev/console", "w");
135 fprintf(f, "%s\en", msg);
145 example% \fBcc printmsg.c -o printmsg\fP
146 example% \fBprintmsg "Hello, there."\fP
153 was turned into a remote procedure,
154 then it could be called from anywhere in the network.
155 Ideally, one would just like to stick a keyword like
158 procedure to turn it into a remote procedure. Unfortunately,
159 we have to live within the constraints of the C language, since
160 it existed long before RPC did. But even without language
161 support, it's not very difficult to make a procedure remote.
163 In general, it's necessary to figure out what the types are for
164 all procedure inputs and outputs. In this case, we have a
167 which takes a string as input, and returns an integer
168 as output. Knowing this, we can write a protocol specification in RPC
169 language that describes the remote version of
176 * msg.x: Remote message printing protocol
180 program MESSAGEPROG {
181 version MESSAGEVERS {
182 int PRINTMESSAGE(string) = 1;
187 Remote procedures are part of remote programs, so we actually declared
188 an entire remote program here which contains the single procedure
190 This procedure was declared to be in version 1 of the
191 remote program. No null procedure (procedure 0) is necessary because
193 generates it automatically.
195 Notice that everything is declared with all capital letters. This is
196 not required, but is a good convention to follow.
198 Notice also that the argument type is \*Qstring\*U and not \*Qchar *\*U. This
199 is because a \*Qchar *\*U in C is ambiguous. Programmers usually intend it
200 to mean a null-terminated string of characters, but it could also
201 represent a pointer to a single character or a pointer to an array of
202 characters. In RPC language, a null-terminated string is
203 unambiguously called a \*Qstring\*U.
205 There are just two more things to write. First, there is the remote
206 procedure itself. Here's the definition of a remote procedure
209 procedure we declared above:
215 * msg_proc.c: implementation of the remote procedure "printmessage"
220 #include <rpc/rpc.h> /* \fIalways needed\fP */
221 #include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */
225 * Remote verson of "printmessage"
232 static int result; /* \fImust be static!\fP */
235 f = fopen("/dev/console", "w");
240 fprintf(f, "%s\en", *msg);
248 Notice here that the declaration of the remote procedure
250 differs from that of the local procedure
254 It takes a pointer to a string instead of a string itself. This
255 is true of all remote procedures: they always take pointers to their
256 arguments rather than the arguments themselves.
258 It returns a pointer to an integer instead of an integer itself. This is
259 also generally true of remote procedures: they always return a pointer
262 It has an \*Q_1\*U appended to its name. In general, all remote
265 are named by the following rule: the name in the program definition
269 lower-case letters, an underbar (\*Q_\*U) is appended to it, and
270 finally the version number (here 1) is appended.
272 The last thing to do is declare the main client program that will call
273 the remote procedure. Here it is:
278 * rprintmsg.c: remote version of "printmsg.c"
282 #include <rpc/rpc.h> /* \fIalways needed\fP */
283 #include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */
295 fprintf(stderr, "usage: %s host message\en", argv[0]);
301 * Save values of command line arguments
309 * Create client "handle" used for calling \fIMESSAGEPROG\fP on the
310 * server designated on the command line. We tell the RPC package
311 * to use the "tcp" protocol when contacting the server.
314 cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, "tcp");
318 * Couldn't establish connection with server.
319 * Print error message and die.
322 clnt_pcreateerror(server);
328 * Call the remote procedure "printmessage" on the server
331 result = printmessage_1(&message, cl);
332 if (result == NULL) {
335 * An error occurred while calling the server.
336 * Print error message and die.
339 clnt_perror(cl, server);
345 * Okay, we successfully called the remote procedure.
351 * Server was unable to print our message.
352 * Print error message and die.
355 fprintf(stderr, "%s: %s couldn't print your message\en",
362 * The message got printed on the server's console
365 printf("Message delivered to %s!\en", server);
368 There are two things to note here:
370 .IX "client handle, used by rpcgen" "" "client handle, used by \fIrpcgen\fP"
371 First a client \*Qhandle\*U is created using the RPC library routine
373 This client handle will be passed to the stub routines
374 which call the remote procedure.
378 is called exactly the same way as it is declared in
380 except for the inserted client handle as the first argument.
382 Here's how to put all of the pieces together:
386 example% \fBrpcgen msg.x\fP
387 example% \fBcc rprintmsg.c msg_clnt.c -o rprintmsg\fP
388 example% \fBcc msg_proc.c msg_svc.c -o msg_server\fP
390 Two programs were compiled here: the client program
392 and the server program
394 Before doing this though,
396 was used to fill in the missing pieces.
400 did with the input file
403 It created a header file called
412 for use in the other modules.
414 It created client \*Qstub\*U routines in the
416 file. In this case there is only one, the
418 that was referred to from the
420 client program. The name of the output file for
421 client stub routines is always formed in this way: if the name of the
424 the client stubs output file is called
427 It created the server program which calls
431 This server program is named
433 The rule for naming the server output file is similar to the
434 previous one: for an input file called
436 the output server file is named
439 Now we're ready to have some fun. First, copy the server to a
440 remote machine and run it. For this example, the
441 machine is called \*Qmoon\*U. Server processes are run in the
442 background, because they never exit.
446 moon% \fBmsg_server &\fP
448 Then on our local machine (\*Qsun\*U) we can print a message on \*Qmoon\*Us
453 sun% \fBprintmsg moon "Hello, moon."\fP
455 The message will get printed to \*Qmoon\*Us console. You can print a
456 message on anybody's console (including your own) with this program if
457 you are able to copy the server to their machine and run it.
459 \&Generating XDR Routines
460 .IX RPC "generating XDR routines"
462 The previous example only demonstrated the automatic generation of
463 client and server RPC code.
465 may also be used to generate XDR routines, that is, the routines
466 necessary to convert local data
467 structures into network format and vice-versa. This example presents
468 a complete RPC service\(ema remote directory listing service, which uses
470 not only to generate stub routines, but also to generate the XDR
471 routines. Here is the protocol description file:
476 * dir.x: Remote directory listing protocol
479 const MAXNAMELEN = 255; /* \fImaximum length of a directory entry\fP */
481 typedef string nametype<MAXNAMELEN>; /* \fIa directory entry\fP */
483 typedef struct namenode *namelist; /* \fIa link in the listing\fP */
487 * A node in the directory listing
491 nametype name; /* \fIname of directory entry\fP */
492 namelist next; /* \fInext entry\fP */
497 * The result of a READDIR operation.
500 union readdir_res switch (int errno) {
502 namelist list; /* \fIno error: return directory listing\fP */
504 void; /* \fIerror occurred: nothing else to return\fP */
509 * The directory program definition
515 READDIR(nametype) = 1;
524 in the example above) can be defined using
525 the \*Qstruct\*U, \*Qunion\*U and \*Qenum\*U keywords, but those keywords
526 should not be used in subsequent declarations of variables of those types.
527 For example, if you define a union \*Qfoo\*U, you should declare using
528 only \*Qfoo\*U and not \*Qunion foo\*U. In fact,
531 RPC unions into C structures and it is an error to declare them using the
538 creates four output files. Three are the same as before: header file,
539 client stub routines and server skeleton. The fourth are the XDR routines
540 necessary for converting the data types we declared into XDR format and
541 vice-versa. These are output in the file
544 Here is the implementation of the
552 * dir_proc.c: remote readdir implementation
560 extern char *malloc();
561 extern char *strdup();
571 static readdir_res res; /* \fImust be static\fP! */
578 dirp = opendir(*dirname);
586 * Free previous result
589 xdr_free(xdr_readdir_res, &res);
593 * Collect directory entries.
594 * Memory allocated here will be freed by \fIxdr_free\fP
595 * next time \fIreaddir_1\fP is called
598 nlp = &res.readdir_res_u.list;
599 while (d = readdir(dirp)) {
600 nl = *nlp = (namenode *) malloc(sizeof(namenode));
601 nl->name = strdup(d->d_name);
617 Finally, there is the client side program to call the server:
622 * rls.c: Remote directory listing client
626 #include <rpc/rpc.h> /* \fIalways need this\fP */
627 #include "dir.h" /* \fIwill be generated by rpcgen\fP */
643 fprintf(stderr, "usage: %s host directory\en",
650 * Remember what our command line arguments refer to
658 * Create client "handle" used for calling \fIMESSAGEPROG\fP on the
659 * server designated on the command line. We tell the RPC package
660 * to use the "tcp" protocol when contacting the server.
663 cl = clnt_create(server, DIRPROG, DIRVERS, "tcp");
667 * Couldn't establish connection with server.
668 * Print error message and die.
671 clnt_pcreateerror(server);
677 * Call the remote procedure \fIreaddir\fP on the server
680 result = readdir_1(&dir, cl);
681 if (result == NULL) {
684 * An error occurred while calling the server.
685 * Print error message and die.
688 clnt_perror(cl, server);
694 * Okay, we successfully called the remote procedure.
697 if (result->errno != 0) {
700 * A remote system error occurred.
701 * Print error message and die.
704 errno = result->errno;
711 * Successfully got a directory listing.
715 for (nl = result->readdir_res_u.list; nl != NULL;
717 printf("%s\en", nl->name);
722 Compile everything, and run.
725 sun% \fBrpcgen dir.x\fP
726 sun% \fBcc rls.c dir_clnt.c dir_xdr.c -o rls\fP
727 sun% \fBcc dir_svc.c dir_proc.c dir_xdr.c -o dir_svc\fP
731 moon% \fBrls sun /usr/pub\fP
745 .IX "debugging with rpcgen" "" "debugging with \fIrpcgen\fP"
748 The client program and the server procedure can be tested together
749 as a single program by simply linking them with each other rather
750 than with the client and server stubs. The procedure calls will be
751 executed as ordinary local procedure calls and the program can be
752 debugged with a local debugger such as
754 When the program is working, the client program can be linked to
755 the client stub produced by
757 and the server procedures can be linked to the server stub produced
762 \fIIf you do this, you may want to comment out calls to RPC library
763 routines, and have client-side routines call server routines
768 .IX rpcgen "C-preprocessor" \fIrpcgen\fP
770 The C-preprocessor is run on all input files before they are
771 compiled, so all the preprocessor directives are legal within a \*Q.x\*U
772 file. Four symbols may be defined, depending upon which output file is
773 getting generated. The symbols are:
780 RPC_HDR&for header-file output
781 RPC_XDR&for XDR routine output
782 RPC_SVC&for server-skeleton output
783 RPC_CLNT&for client stub output
788 does a little preprocessing of its own. Any line that
789 begins with a percent sign is passed directly into the output file,
790 without any interpretation of the line. Here is a simple example that
791 demonstrates the preprocessing features.
796 * time.x: Remote time protocol
801 unsigned int TIMEGET(void) = 1;
809 % static int thetime;
816 The '%' feature is not generally recommended, as there is no guarantee
817 that the compiler will stick the output where you intended.
819 \&\fBrpcgen\fP Programming Notes
820 .IX rpcgen "other operations" \fIrpcgen\fP
824 .IX rpcgen "timeout changes" \fIrpcgen\fP
826 RPC sets a default timeout of 25 seconds for RPC calls when
828 is used. This timeout may be changed using
830 Here is a small code fragment to demonstrate use of
836 cl = clnt_create("somehost", SOMEPROG, SOMEVERS, "tcp");
840 tv.tv_sec = 60; /* \fIchange timeout to 1 minute\fP */
842 clnt_control(cl, CLSET_TIMEOUT, &tv);
845 \&Handling Broadcast on the Server Side
847 .IX rpcgen "broadcast RPC" \fIrpcgen\fP
849 When a procedure is known to be called via broadcast RPC,
850 it is usually wise for the server to not reply unless it can provide
851 some useful information to the client. This prevents the network
852 from getting flooded by useless replies.
854 To prevent the server from replying, a remote procedure can
855 return NULL as its result, and the server code generated by
857 will detect this and not send out a reply.
859 Here is an example of a procedure that replies only if it
860 thinks it is an NFS server:
865 char notnull; /* \fIjust here so we can use its address\fP */
867 if (access("/etc/exports", F_OK) < 0) {
868 return (NULL); /* \fIprevent RPC from replying\fP */
872 * return non-null pointer so RPC will send out a reply
875 return ((void *)¬null);
878 Note that if procedure returns type \*Qvoid *\*U, they must return a non-NULL
879 pointer if they want RPC to reply for them.
881 \&Other Information Passed to Server Procedures
883 Server procedures will often want to know more about an RPC call
884 than just its arguments. For example, getting authentication information
885 is important to procedures that want to implement some level of security.
886 This extra information is actually supplied to the server procedure as a
887 second argument. Here is an example to demonstrate its use. What we've
888 done here is rewrite the previous
890 procedure to only allow root users to print a message to the console.
893 printmessage_1(msg, rq)
897 static in result; /* \fIMust be static\fP */
899 struct suthunix_parms *aup;
901 aup = (struct authunix_parms *)rq->rq_clntcred;
902 if (aup->aup_uid != 0) {
909 * Same code as before.
917 .IX rpcgen "RPC Language" \fIrpcgen\fP
919 RPC language is an extension of XDR language. The sole extension is
922 type. For a complete description of the XDR language syntax, see the
923 .I "External Data Representation Standard: Protocol Specification"
924 chapter. For a description of the RPC extensions to the XDR language,
926 .I "Remote Procedure Calls: Protocol Specification"
929 However, XDR language is so close to C that if you know C, you know most
930 of it already. We describe here the syntax of the RPC language,
931 showing a few examples along the way. We also show how the various
932 RPC and XDR type definitions get compiled into C type definitions in
933 the output header file.
938 .IX rpcgen definitions \fIrpcgen\fP
940 An RPC language file consists of a series of definitions.
945 definition ";" definition-list
948 It recognizes five types of definitions.
962 .IX rpcgen structures \fIrpcgen\fP
964 An XDR struct is declared almost exactly like its C counterpart. It
965 looks like the following:
969 "struct" struct-ident "{"
975 declaration ";" declaration-list
977 As an example, here is an XDR structure to a two-dimensional
978 coordinate, and the C structure that it gets compiled into in the
982 struct coord { struct coord {
986 typedef struct coord coord;
988 The output is identical to the input, except for the added
990 at the end of the output. This allows one to use \*Qcoord\*U instead of
991 \*Qstruct coord\*U when declaring items.
995 .IX rpcgen unions \fIrpcgen\fP
997 XDR unions are discriminated unions, and look quite different from C
998 unions. They are more analogous to Pascal variant records than they
1003 "union" union-ident "switch" "(" declaration ")" "{"
1008 "case" value ":" declaration ";"
1009 "default" ":" declaration ";"
1010 "case" value ":" declaration ";" case-list
1012 Here is an example of a type that might be returned as the result of a
1013 \*Qread data\*U operation. If there is no error, return a block of data.
1014 Otherwise, don't return anything.
1017 union read_result switch (int errno) {
1024 It gets compiled into the following:
1027 struct read_result {
1033 typedef struct read_result read_result;
1035 Notice that the union component of the output struct has the name as
1036 the type name, except for the trailing \*Q_u\*U.
1040 .IX rpcgen enumerations \fIrpcgen\fP
1042 XDR enumerations have the same syntax as C enumerations.
1046 "enum" enum-ident "{"
1052 enum-value "," enum-value-list
1056 enum-value-ident "=" value
1058 Here is a short example of an XDR enum, and the C enum that it gets
1062 enum colortype { enum colortype {
1064 GREEN = 1, --> GREEN = 1,
1067 typedef enum colortype colortype;
1072 .IX rpcgen typedef \fIrpcgen\fP
1074 XDR typedefs have the same syntax as C typedefs.
1078 "typedef" declaration
1080 Here is an example that defines a
1083 file name strings that have a maximum length of 255 characters.
1086 typedef string fname_type<255>; --> typedef char *fname_type;
1091 .IX rpcgen constants \fIrpcgen\fP
1093 XDR constants symbolic constants that may be used wherever a
1094 integer constant is used, for example, in array size specifications.
1098 "const" const-ident "=" integer
1100 For example, the following defines a constant
1105 const DOZEN = 12; --> #define DOZEN 12
1110 .IX rpcgen programs \fIrpcgen\fP
1112 RPC programs are declared using the following syntax:
1116 "program" program-ident "{"
1122 version ";" version-list
1125 "version" version-ident "{"
1131 procedure ";" procedure-list
1134 type-ident procedure-ident "(" type-ident ")" "=" value
1136 For example, here is the time protocol, revisited:
1141 * time.x: Get or set the time. Time is represented as number of seconds
1142 * since 0:00, January 1, 1970.
1147 unsigned int TIMEGET(void) = 1;
1148 void TIMESET(unsigned) = 2;
1152 This file compiles into #defines in the output header file:
1164 .IX rpcgen declarations \fIrpcgen\fP
1166 In XDR, there are only four kinds of declarations.
1171 fixed-array-declaration
1172 variable-array-declaration
1175 \fB1) Simple declarations\fP are just like simple C declarations.
1179 type-ident variable-ident
1184 colortype color; --> colortype color;
1186 \fB2) Fixed-length Array Declarations\fP are just like C array declarations:
1189 fixed-array-declaration:
1190 type-ident variable-ident "[" value "]"
1195 colortype palette[8]; --> colortype palette[8];
1197 \fB3) Variable-Length Array Declarations\fP have no explicit syntax
1198 in C, so XDR invents its own using angle-brackets.
1201 variable-array-declaration:
1202 type-ident variable-ident "<" value ">"
1203 type-ident variable-ident "<" ">"
1205 The maximum size is specified between the angle brackets. The size may
1206 be omitted, indicating that the array may be of any size.
1209 int heights<12>; /* \fIat most 12 items\fP */
1210 int widths<>; /* \fIany number of items\fP */
1212 Since variable-length arrays have no explicit syntax in C, these
1213 declarations are actually compiled into \*Qstruct\*Us. For example, the
1214 \*Qheights\*U declaration gets compiled into the following struct:
1218 u_int heights_len; /* \fI# of items in array\fP */
1219 int *heights_val; /* \fIpointer to array\fP */
1222 Note that the number of items in the array is stored in the \*Q_len\*U
1223 component and the pointer to the array is stored in the \*Q_val\*U
1224 component. The first part of each of these component's names is the
1225 same as the name of the declared XDR variable.
1227 \fB4) Pointer Declarations\fP are made in
1228 XDR exactly as they are in C. You can't
1229 really send pointers over the network, but you can use XDR pointers
1230 for sending recursive data types such as lists and trees. The type is
1231 actually called \*Qoptional-data\*U, not \*Qpointer\*U, in XDR language.
1234 pointer-declaration:
1235 type-ident "*" variable-ident
1240 listitem *next; --> listitem *next;
1244 .IX rpcgen "special cases" \fIrpcgen\fP
1246 There are a few exceptions to the rules described above.
1249 C has no built-in boolean type. However, the RPC library does a
1256 Things declared as type
1258 in XDR language are compiled into
1260 in the output header file.
1265 bool married; --> bool_t married;
1268 C has no built-in string type, but instead uses the null-terminated
1269 \*Qchar *\*U convention. In XDR language, strings are declared using the
1270 \*Qstring\*U keyword, and compiled into \*Qchar *\*Us in the output header
1271 file. The maximum size contained in the angle brackets specifies the
1272 maximum number of characters allowed in the strings (not counting the
1274 character). The maximum size may be left off, indicating a string
1275 of arbitrary length.
1280 string name<32>; --> char *name;
1281 string longname<>; --> char *longname;
1284 Opaque data is used in RPC and XDR to describe untyped data, that is,
1285 just sequences of arbitrary bytes. It may be declared either as a
1286 fixed or variable length array.
1290 opaque diskblock[512]; --> char diskblock[512];
1292 opaque filedata<1024>; --> struct {
1298 In a void declaration, the variable is not named. The declaration is
1299 just \*Qvoid\*U and nothing else. Void declarations can only occur in two
1300 places: union definitions and program definitions (as the argument or
1301 result of a remote procedure).