next up previous contents
Next: PowerRPC library functions Up: Contents Previous: Type declarations in the

Interface declarations in the powerRPC IDL

We have seen a simple example of the interface declaration in section 0.1.1. Now that we have learned how to declare types, what remains is simple: to declare RPC functions, using the declared types in function signatures or as return types.

Syntax

A powerRPC IDL files may contain the following components,

  1. C preprocessor pseudo-ops, such as #include. powerRPC will pass the IDL file through CPP before performing its own parsing. It also defines a macro POWERRPC_COMPILE by itself when invoking CPP.
  2. type declarations, as described in chapter 1.
  3. A single interface declaration which specifies the RPC functions. This must appear after all type declarations.
  4. copy-out statements. These are arbitrary text followed by a leading %. They are copied AS IS to the header file generated by powerRPC. Those appear before the interface declaration are prepended to the header file, and those appear after are appended to the header file.

Interface declaration...

Interface declaration by example

An interface declaration consists property definitions and functions declarations.

The following is an example,

1  interface test {
2     property TRANSPORT_PROTOCOL = tcp;
3     int my_read(
4         out char [maxsize=maxlen, size=return>0?return:0] buf,
5             int maxlen
6         )
7        {
8            property FORK_ON_CALL = true;
10       };
12    int my_write(in char [size = len] buf, int len);
13 } = 12221;
At line 1, the keyword interface followed by the identifier test announces our RPC. At line 2, we set the TRANSPORT PROTOCOL of the RPC to be TCP. Properties are optional settings that customize RPCes on the client or server side. If the TRANSPORT_PROTOCOL property is not set, the default is tcp_and_udp, meaning the client can connect to the server via both protocols. From line 3 to line 10, we declared an RPC function my_read(char* buf, int maxlen), the out keyword on line 4 says that the buf is used for output only, and its maximum size is determined by the second argument maxlen, its size is determined by the expression (return > 0? return:0), where the return keyword is the return value of the RPC function. Obviously, return can ONLY be used in size expressions for out arguments. The FORK_ON_CALL property says that the RPC server will fork a child upon receiving the my_read() call, so the parent can handle other requests. Line 12 declares another RPC function int my_write(char* buf, int len), in this case, the buf is used for input only, the size of buf is determined by the len argument. my_write() does not have additional properties, unlike my_read(), the server will not fork a child to handle it. Line 13 specifies that the test RPC is identified by the program number 12221. The program number is a long integer used to identify the RPC program, and it should not be in conflict with other RPC programs.

PowerRPC IDL allows you to specify the direction of the argument as one of in, out and inout, the default direction is in. You can use an argument in the size expression for an array argument.

The property definitions have scopes. When a property is defined in the scope of the interface, it is shared by all RPC functions. However, a function can redefines a particular property, and overrides the common value.

RPC properties are very useful in customizing how RPC works. They can be a boolean that toggle between options, or a value to set a parameter, or a function to be called at a particular point.

RPC function declaration

RPC function declarations should be enclosed in the body of the interface declaration. A function can use any of the types declared previously in the IDL file. An array argument can use an argument of the same function in its size expressions. Thus, we can have the following,

interface hello {
        void printmsg(char [size=strlen(msg)+1, 1024] msg);
} 0x12345;

A function argument can be of one of the three directions,

in
The argument is only to be sent to the server. This is the default (when no direction is specified for an argument).
out
The argument is used only to receive result from server, it must be a pointer or an array.
inout
The argument is used for both sending and receiving data, it must be a pointer or an array.

The return type of an RPC function can also be of any type. However, you must note that for a functions that return a pointer, powerRPC allocates the memory to which the pointer points, and it is the programmer responsibility to free that memory using the library function pw_free_reference().

Property definitions

As shown in the previous examples, property definitions come in two places: immediately enclosed in the ``body" of an interface declaration, or inside the ``body" of a function declaration.

The following properties can be defined.

VERSION

An integer value to specified version number for the interface.

The default value is 1.

TRANSPORT_PROTOCOL

The protocol used by client/server for communications. Choices are

tcp
A connection-oriented reliable protocol, with exactly once calling semantics.
udp
A connectionless unreliable protocol. The client would retransmit the RPC call if not receive response within a timeout period. Another restriction is that UDP datagrams usually have a maximum size of 8K bytes, so it may not be suitable for RPC functions whose arguments or return value are large.

tcp_and_udp
The server will register with both protocols. The client can choose either one of them, with the default being TCP.

The default is tcp_and_udp.

SERVER_PORT

An integer value used to specify to the port number of the RPC server. When this property is not set (the usual case), the server choose an arbitrary port that is available and the client consults the portmapper on the server host to obtain the port number. When this set, the client will bypass the portmapper and uses the port number specified.

NO_PMAP_REGISTER

When this property is set to true, the server will skip registration with the portmapper. The rpcinfo command won't find your server. You would normally set this property when you also specified a fixed port.

The default is false.

INIT_BEFORE_REGISTER

A user defined function to be called before server register itself. This function must be of the type of void (*) (int, char**), it is passed the argc and argv arguments from the main(int argc, char**argv) function.

No default value for this property.

INIT_AFTER_REGISTER

The user defined function to be called after server register itself. This function will be passed the argc and argv arguments from the main(int argc, char**argv) function.

For example, you could use this initialization function to set up signal handlers, a useful one is to unregister your RPC server with the portmapper when a SIGINT is received. Using the quote RPC server as an example, we can write the following functions,

        void handler(int sig) 
        {
                quote_1_unmap(0,0);
                exit(0);
        }

        void set_sigint_handler(int argc, char**argv)
        {
              signal(SIGINT, handler);
        }
where quote_1_unmap() is a function generated by powerRPC for the purpose of unsetting the portmapper entry of the quote server. By setting
        INIT_AFTER_REGISTER = set_sigint_handler;
you make sure that the quote server will remove its entry from the portmapper's database.

No default value for this property.

GEN_MAIN_FUNC

When set to false, the powerRPC compiler will not generate the main() function for the server.

The default is true.

FORK_ON_CONNECTION

When set to true, the RPC server will fork a dedicated server for each client, all RPCes from the client will be handled by the child. For TCP, the child is created when a request for connection is received, when the client detaches from the server, the forked child will exit. The semantics with UDP transport is different, since UDP is not connection oriented. For UDP, the server would fork to handle each incoming RPC call. It is recommended not to use this option with UDP transport, use FORK_ON_CALL instead.

The default is false.

FORK_ON_CALL

When set to true for an RPC function, the server will fork a child to handle the call, so itself can still handle other requests.

The forked child will exit at the completion of the call.

The default is false.

NON_BLOCKING

When this is set to true for an RPC function, the server will reply to the server immediately, before it actually calls the user implementation of the function.

Obviously, the return type of such an RPC function should be void and it should have no out or inout arguments.

TIMEOUT_VALUE

This is an integral value for the RPC timeout in seconds on the client side. When specified for an RPC function, a timeout error will occur when a reply for this function is not received within the timeout.

For example, if you set this to be 0 for function foo(), then every call of foo() will timeout.

The default value is 60.

SERV_CALL_PREFIX

For an RPC function foo() , the powerRPC compiler will generate the client definition of foo() for you, and you must write the server implementation of foo() yourself. However, sometimes, you want to make a program both a server and a client of the same RPC interface. To make this possible, you must set this property.

For example, when you set

      property SERV_CALL_PREFIX = serv_ ;
powerRPC expects your sever implementation of foo() to be serv_foo(). This solve the name conflict and you can write a program that is both a server and also a client (of another server) of the same RPC.

Functions in the generated code

Various functions are generated from your IDL file, occasionally, you may want to call them in your code directly.

XDR functions

For any data type T used in an RPC function, an XDR function bool_t xdr_T(XDR* xdrs, T*ptr) is generated when T is not one of the primitive types. This function takes a pointer to an object of type T as the second argument, and performs encode, decode or free operation based on the value of xdrs->x_op.

One possible use of the XDR functions is for serializing data to and from files.

Client side functions

CLIENT* <interface>_bind(char*host, u_long pno, u_long vno, char*protocol)


Parameters:

host
the host name of the RPC server
pno
the RPC program number. When this is 0, the one specified in the interface is used.
vno
the RPC version number. When this is 0, the one specified in the interface is used.
protocol
``tcp" or ``udp". When this is 0, the one specified in the interface is used.

Return value: On success, it returns a pointer to CLIENT struct. On failure, it returns NULL.

This function binds the client to the RPC server specified by the parameters. All subsequent RPC calls go to the specified server. The client application may save the returned client handle, so it can talk to multiple servers.

void <interface>_bind_handle(CLIENT*pclnt)


Parameters:

pclnt
a valid client handle returned from a previous call to <interface>_bind().

This function binds the client to a previously bound server. All subsequent RPC calls go to this server.

void <interface>_unbind(CLIENT*pclnt)


Parameters:

pclnt
a client handle returned from a previous call to <interface>_bind(). If this is NULL, defaults to the current client handle.

This function unbinds the client to a server.

enum clnt_stat <interface>_errno(CLIENT*pclnt)


Parameters:

pclnt
a client handle returned from a previous call to <interface>_bind(). If this is NULL, defaults to the current client handle.

This function returns the RPC call status after an RPC has been made. If this is not RPC_SUCCESS, an error condition has occured.

Server functions

SVCXPRT* <interface>_<version>_reg(int sock, u_long pno, u_long vno, int protocol)


Parameters:

sock
a bound socket or RPC_ANYSOCK.
pno
the RPC program number. When this is 0, the one specified in the interface is used.
vno
the RPC version number. When this is 0, the one specified in the interface is used.
protocol
IPPROTO_TCP or IPPROTO_UDP.

Return value:

A pointer to the server transport. NULL on failure.

This function takes register the <interface> RPC server with the specified parameters.

void <interface>_<version>_main(int argc, char**argv)


Parameters:

argc
Number of command line arguments.
argv
The array of command line arguments.

This function starts the RPC server. It should never return.

void <interface>_unmap (u_long pno, u_long vno)


Parameters:

pno
the RPC program number. When this is 0, the one specified in the interface is used.
vno
the RPC version number. When this is 0, the one specified in the interface is used.

This function undo the RPC server registration with the portmapper.

PowerRPC library...


next up previous contents
Next: PowerRPC library functions Up: Contents Previous: Type declarations in the

Copyright (C) Netbula LLC, 1996