Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
8.  Extensions to the Sun RPC Library Client Connection Closure Callback Example of client connection closure callback  Previous   Contents   Next 
   
 

The logClient.c file shows a client using the log server.

#include "log.h"
#include <stdio.h>

#define MSG_SIZE 128

    void
usage()
{
    puts("Usage: logClient <logserver_addr>");
    exit(2);
}

    void
runClient(CLIENT* clnt)
{
    char msg[MSG_SIZE];
    int logID;
    int* result;
    
		 /*
 	  * client opens a log
 	  */
    result = openlog_1("client", clnt);
    if (NULL == result) {
        clnt_perror(clnt, "openlog");
        return;
    }
    logID = *result;
    if (-1 == logID) {
        puts("Cannot open the log.");
        return;
    }
    
    while(1) {
        struct rpc_err e;
        
			 /*
		 	  * Client writes a message in the log
		 	  */
        puts("Enter a message in the log (\".\" to quit):");
        fgets(msg, MSG_SIZE, stdin);
        /* 
				* Remove trailing CR 
				*/
        msg[strlen(msg)-1] = 0;
        
        if (!strcmp(msg, ".")) break;
    
        if (writelog_1(logID, LOG_INFO, msg, clnt) == NULL) {
            clnt_perror(clnt, "writelog");
            return;
        }
    }
		 /*
		  * Client closes the log
		  */
    result = closelog_1(logID, clnt);
    if (NULL == result) {
        clnt_perror(clnt, "closelog");
        return;
    }
    logID = *result;
    if (-1 == logID) {
        puts("Cannot close the log.");
        return;
    }
}

    int
main(int argc, char* argv[])
{
    char* serv_addr;
    CLIENT* clnt;
    
    if (argc != 2) usage();

    serv_addr = argv[1];

    clnt = clnt_create(serv_addr, LOG, LOG_VERS1, "tcp");

    if (NULL == clnt) {
        clnt_pcreateerror("Cannot connect to log server");
        exit(1);
    }
    runClient(clnt);

    clnt_destroy(clnt);
}

User File Descriptor Callbacks

User file descriptor callbacks enable you to register file descriptors with callbacks, specifying one or more event types. Now you can use an RPC server to handle file descriptors that were not written for the Sun RPC library.

With previous versions of the Sun RPC library, you could use a server to receive both RPC calls and non-RPC file descriptors only if you wrote your own server loop, or used a separate thread to contact the socket API.

For user file descriptor callbacks, two new functions have been added to the Sun RPC library, svc_add_input(3NSL) and svc_remove_input(3NSL), to implement user file descriptor callbacks. These functions declare or remove a callback on a file descriptor.

When using this new callback feature you must:

  • Create your callback() function by writing user code with the following syntax:

    typedef void (*svc_callback_t) (svc_input_id_t id, int fd, \ unsigned 
                   int revents, void* cookie);

    The four parameters passed to the callback() function are:
    id

    Provides an identifier for each callback. This identifier can be used to remove a callback.

    fd

    The file descriptor that your callback is waiting for.

    revents

    An unsigned integer representing the events that have occurred. This set of events is a subset of the list given when the callback is registered.

    cookie

    The cookie given when the callback is registered. This cookie can be a pointer to specific data the server needs during the callback.

  • Call svc_add_input() to register file descriptors and associated events, such as read or write, that the server must be aware of.
    svc_input_id_t svc_add_input (int fd, unsigned int revents, \
    svc_callback_t callback, void* cookie);
    A list of the events that can be specified is given inpoll(2) .

  • Specify a file descriptor. This file descriptor can be an entity such as a socket or a file.

When one of the specified events occurs, the standard server loop calls the user code through svc_run() and your callback performs the required operation on the file descriptor, socket or file.

When you no longer need a particular callback, call svc_remove_input() with the corresponding identifier to remove the callback.

 
 
 
  Previous   Contents   Next