Исходные коды спецификаций для LSB Core 3.1

/*
 * Copyright (c) 2005-2006 Institute for System Programming
 * Russian Academy of Sciences
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Portions of this text are reprinted and reproduced in electronic form
 * from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology
 * -- Portable Operating System Interface (POSIX), The Open Group Base
 * Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of
 * Electrical and Electronics Engineers, Inc and The Open Group. In the
 * event of any discrepancy between this version and the original IEEE and
 * The Open Group Standard, the original IEEE and The Open Group Standard
 * is the referee document. The original Standard can be obtained online at
 * http://www.opengroup.org/unix/online.html.
 */

#include "socket/rpc/svc_model.seh"
#include "process/process/process_model.seh"

#pragma SEC subsystem rpc "socket.rpc"


/*
   The group of functions 'socket.rpc.svc' consists of:
       svc_getreqset [2]
       svcerr_auth [2]
       svcerr_decode [2]
       svcerr_noproc [2]
       svcerr_noprog [2]
       svcerr_progvers [2]
       svcerr_systemerr [2]
       svcerr_weakauth [2]

       svc_register [3]
       svc_run [3]
       svc_sendreply [3]
       svctcp_create [3]
       svcudp_create [3]
 */

/********************************************************************/
/**                      Interface Functions                       **/
/********************************************************************/

/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group

    refers

System V Interface Definition, Fourth Edition
FINAL COPY June 15, 1995
Copyright (c) 1983, 1984, 1985, 1986,1987, 1988, 1995 Novell, Inc.

SYNOPSIS

    #include <rpc/rpc.h>

    extern void svc_getreqset(fd_set *);
    extern void svcerr_auth(SVCXPRT *, enum auth_stat);
    extern void svcerr_decode(SVCXPRT *);
    extern void svcerr_noproc(SVCXPRT *);
    extern void svcerr_noprog(SVCXPRT *);
    extern void svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t);
    extern void svcerr_systemerr(SVCXPRT *);
    extern void svcerr_weakauth(SVCXPRT *);

    #define svc_freeargs(xprt,xargs, argsp) \
            (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
    #define svc_getargs(xprt,xargs, argsp) \
            (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))

DESCRIPTION

    void
    svc_getreqset(fd_set *rdfds);

        This routine is only of interest if a service implementor does not call
        svc_run(), but instead implements custom asynchronous event processing. It is
        called when poll() has determined that an RPC request has arrived on some RPC
        file descriptors; rdfds is the resultant read file descriptor bit mask. The
        routine returns when all file descriptors associated with the value of rdfds
        have been serviced

    void
    svcerr_auth(const SVCXPRT *xprt, const enum auth_stat why);

        Called by a service dispatch routine that refuses to perform a remote procedure
        call due to an authentication error.

    void
    svcerr_decode(const SVCXPRT *xprt);

        Called by a service dispatch routine that cannot successfully decode the
        remote parameters [see svc_getargs() in rpc_svc_reg(RS_LIB)].

    void
    svcerr_noproc(const SVCXPRT *xprt);

        Called by a service dispatch routine that does not implement the procedure
        number that the caller requests.

    void
    svcerr_noprog(const SVCXPRT *xprt);

        Called when the desired program is not registered with the RPC package.
        Service implementors usually do not need this routine.

    void
    svcerr_progvers(const SVCXPRT *xprt);

        Called when the desired version of a program is not registered with the RPC
        package. Service implementors usually do not need this routine.

    void
    svcerr_systemerr(const SVCXPRT *xprt);

        Called by a service dispatch routine when it detects a system error not
        covered by any particular protocol. For example, if a service can no longer
        allocate storage, it may call this routine.

    void
    svcerr_weakauth(const SVCXPRT *xprt);

        Called by a service dispatch routine that refuses to perform a remote procedure
        call due to insufficient (but correct) authentication parameters. The routine
        calls svcerr_auth(xprt, AUTH_TOOWEAK).

    bool_t
    svc_freeargs(const SVCXPRT *xprt, const xdrproc_t inproc, char *in);

        A function macro that frees any data allocated by the RPC/XDR system when it
        decoded the arguments to a service procedure using svc_getargs(). This routine
        returns 1 if the results were successfully freed, and 0 otherwise.

    bool_t
    svc_getargs(const SVCXPRT *xprt, const xdrproc_t inproc, char *in);

        A function macro that decodes the arguments of an RPC request associated with
        the RPC service transport handle xprt. The parameter in is the address where
        the arguments will be placed; inproc is the XDR routine used to decode the
        arguments. This routine returns 1 if decoding succeeds, and 0 otherwise.

*/

specification
void svc_getreqset_spec(CallContext context, FdSetTPtr rdfds)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * This routine is only of interest if a service implementor does not call
         * svc_run(), but instead implements custom asynchronous event processing.
         */
        REQ("svc_getreqset.01", "", TODO_REQ());

        /*
         * It is called when poll() has determined that an RPC request has arrived on some
         * RPC file descriptors;
         */
        REQ("svc_getreqset.02", "", TODO_REQ());

        /*
         * The routine returns when all file descriptors associated with the value of
         * rdfds have been serviced
         */
        REQ("svc_getreqset.03", "", TODO_REQ());
        
        return true;    
    }
}


specification
void svcerr_auth_spec(CallContext context, SvcXprtTPtr xprt, enum AuthStatT why)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * Called by a service dispatch routine that refuses to perform a remote procedure
         * call due to an authentication error.
         */
        REQ("svcerr_auth.01", "", TODO_REQ());

        return true;
    }
}


specification
void svcerr_decode_spec(CallContext context, SvcXprtTPtr xprt)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * Called by a service dispatch routine that cannot successfully decode the remote
         * parameters [see svc_getargs() in rpc_svc_reg(RS_LIB)].
         */
        REQ("svcerr_decode.01", "", TODO_REQ());

        return true;
    }
}


specification
void svcerr_noproc_spec(CallContext context, SvcXprtTPtr xprt)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * Called by a service dispatch routine that does not implement the procedure
         * number that the caller requests.
         */
        REQ("svcerr_noproc.01", "", TODO_REQ());

        return true;
    }
}


specification
void svcerr_noprog_spec(CallContext context, SvcXprtTPtr xprt)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
       /*
         * Called when the desired program is not registered with the RPC package.
         */
        REQ("svcerr_noprog.01", "", TODO_REQ());
        
        return true;
    }
}


specification
void svcerr_progvers_spec(CallContext context, SvcXprtTPtr xprt, RpcVersT low_vers, RpcVersT high_vers)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * Called when the desired version of a program is not registered with the RPC
         * package.
         */
        REQ("svcerr_progvers.01", "", TODO_REQ());

        return true;
    }
}


specification
void svcerr_systemerr_spec(CallContext context, SvcXprtTPtr xprt)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
       /*
         * Called by a service dispatch routine when it detects a system error not covered
         * by any particular protocol. For example, if a service can no longer allocate
         * storage, it may call this routine.
         */
        REQ("svcerr_systemerr.01", "", TODO_REQ());
        
        return true;
    }
}


specification
void svcerr_weakauth_spec(CallContext context, SvcXprtTPtr xprt)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
       /*
         * Called by a service dispatch routine that refuses to perform a remote procedure
         * call due to insufficient (but correct) authentication parameters.
         */
        REQ("svcerr_weakauth.01", "", TODO_REQ());

        /*
         * The routine calls svcerr_auth(xprt, AUTH_TOOWEAK).
         */
        REQ("svcerr_weakauth.02", "", TODO_REQ());

        return true;
    }
}


specification
BoolT svc_freeargs_spec(CallContext context, SvcXprtTPtr xprt, XdrProcTPtr inproc, CharTPtr in)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        return true;
    }
}


specification
BoolT svc_getargs_spec(CallContext context, SvcXprtTPtr xprt, XdrProcTPtr inproc, CharTPtr in)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        return true;
    }
}


/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group

NAME

    svc_register -- register Remote Procedure Call interface

SYNOPSIS

    #include <rpc/rpc.h>

    bool_t svc_register(SVCXPRT * xprt, rpcprog_t prognum, rpcvers_t versnum, __dispatch_fn_t dispatch, rpcprot_t protocol);

DESCRIPTION

    The svc_register() function shall associate the program identified by prognum 
    at version versnum with the service dispatch procedure, dispatch. If protocol 
    is zero, the service is not registered with the portmap service. If protocol is 
    non-zero, then a mapping of the triple [prognum, versnum, protocol] to xprt-> 
    xp_port is established with the local portmap service.

    The procedure dispatch has the following form:

    int dispatch(struct svc_req * request, SVCXPRT * xprt);

RETURN VALUE

    svc_register() returns 1 if it succeeds, and zero otherwise.

*/

specification
BoolT svc_register_spec(CallContext context, SvcXprtTPtr xprt, RpcProgT prog, RpcVersT vers, DispatchFnTPtr dispatch, RpcProtT protocol)
{
    pre
    {
        /*
         * The procedure dispatch has the following form:
         * int dispatch(struct svc_req * request, SVCXPRT * xprt);
         */
        REQ("app.svc_register.04", "", TODO_REQ());

        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * The svc_register() function shall associate the program identified by prognum 
         * at version versnum with the service dispatch procedure, dispatch.
         */
        REQ("svc_register.01", "", TODO_REQ());

        /*
         * If protocol is zero, the service is not registered with the portmap service.
         */
        REQ("svc_register.02", "", TODO_REQ());

        /*
         * If protocol is non-zero, then a mapping of the triple [prognum, versnum, 
         * protocol] to xprt->xp_port is established with the local portmap service.
         */
        REQ("svc_register.03", "", TODO_REQ());

        /*
         * svc_register() returns 1 if it succeeds,
         */
        REQ("svc_register.05", "", TODO_REQ());

        /*
         * and zero otherwise.
         */
        REQ("svc_register.06", "", TODO_REQ());

        return true;
    }
}


/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group

NAME

    svc_run -- waits for RPC requests to arrive and calls service procedure

SYNOPSIS

    #include <rpc/svc.h>

    void svc_run(void);

DESCRIPTION

    The svc_run() function shall wait for RPC requests to arrive, read and unpack 
    each request, and dispatch it to the appropriate registered handler. Under 
    normal conditions, svc_run() shall not return; it shall only return if serious 
    errors occur that prevent further processing.

*/

specification
void svc_run_spec(CallContext context)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        return true;
    }
}

void onSvcRun(CallContext context)
{
    startBlockedCall(context, create_IntTObj(0));
}

reaction SvcRunReturnType* svc_run_return(void)
{
    post
    {
        verbose("svc_run STOPPED!\n");
        /*
         * The svc_run() function shall wait for RPC requests to arrive, read and unpack 
         * each request, and dispatch it to the appropriate registered handler.
         */
        REQ("svc_run.01", "", TODO_REQ());

        /*
         * it shall only return if serious errors occur that prevent further processing.
         */
        REQ("svc_run.03", "", TODO_REQ());

        return true;
    }
}

void onSvcRunReturn(CallContext context)
{
    finishBlockedCall(context);
}


/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group

NAME

    svc_sendreply -- called by RPC service's dispatch routine

SYNOPSIS

    bool_t svc_sendreply(SVCXPRT *xprt, xdrproc_t outproc, caddr_t out);

DESCRIPTION

    Called by an RPC service's dispatch routine to send the results of a remote 
    procedure call. The parameter xprt is the request's associated transport handle; 
    outproc is the XDR routine which is used to encode the results; and out is the 
    address of the results. This routine returns one if it succeeds, zero other- 
    wise.

*/

specification
BoolT svc_sendreply_spec(CallContext context, SvcXprtTPtr xprt, XdrProcTPtr outproc, CaddrT out)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * This routine returns one if it succeeds,
         */
        REQ("svc_sendreply.01", "", TODO_REQ());

        /*
         * zero other-wise.
         */
        REQ("svc_sendreply.02", "", TODO_REQ());

        return true;
    }
}


/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group

NAME

    svctcp_create -- create a TCP/IP-based RPC service transport

SYNOPSIS

    #include <rpc/rpc.h>

    SVCXPRT * svctcp_create(int sock, u_int send_buf_size, u_int recv_buf_size);

DESCRIPTION

    svctcp_create() cretes a TCP/IP-based RPC service transport, to which it 
    returns a pointer. The transport is associated with the socket sock, which may 
    be RPC_ANYSOCK, in which case a new socket is created. If the socket is not 
    bound to a local TCP port, then this routine binds it to an arbitrary port. 
    Upon completion, xprt->xp_sock is the transport's socket descriptor, and 
    xprt->xp_port is the transport's port number. Since TCP-based RPC uses 
    buffered I/O, users may specify the size of buffers; values of zero choose 
    suitable defaults.

RETURN VALUE

    svctcp_create() returns NULL if it fails, or a pointer to the RPC service 
    transport otherwise.

*/

specification
SvcXprtTPtr svctcp_create_spec(CallContext context, IntT sock, UIntT sendsize, UIntT recvsize)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * svctcp_create() cretes a TCP/IP-based RPC service transport, to which it 
         * returns a pointer.
         */
        REQ("svctcp_create.01", "", TODO_REQ());

        /*
         * The transport is associated with the socket sock
         */
        REQ("svctcp_create.02", "", TODO_REQ());

        /*
         * which may be RPC_ANYSOCK, in which case a new socket is created.
         */
        REQ("svctcp_create.03", "", TODO_REQ());

        /*
         * If the socket is not bound to a local TCP port, then this routine binds it to 
         * an arbitrary port.
         */
        REQ("svctcp_create.04", "", TODO_REQ());

        /*
         * Upon completion, xprt->xp_sock is the transport's socket descriptor,
         */
        REQ("svctcp_create.05", "", TODO_REQ());

        /*
         * and xprt->xp_port is the transport's port number.
         */
        REQ("svctcp_create.06", "", TODO_REQ());

        /*
         * Since TCP-based RPC uses buffered I/O, users may specify the size of buffers; 
         * values of zero choose suitable defaults.
         */
        REQ("svctcp_create.07", "", TODO_REQ());

        /*
         * svctcp_create() returns NULL if it fails,
         */
        REQ("svctcp_create.08", "", TODO_REQ());

        /*
         * or a pointer to the RPC service transport otherwise.
         */
        REQ("svctcp_create.09", "", TODO_REQ());

        return true;
    }
}


/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group

NAME

    svcudp_create -- create a UDP-based RPC service transport 

SYNOPSIS

    SVCXPRT * svcudp_create(int sock);

DESCRIPTION

    This call is equivalent to svcudp_bufcreate( sock, SZ, SZ) for some default 
    size SZ.

*/

specification
SvcXprtTPtr svcudp_create_spec(CallContext context, IntT sock)
{
    pre
    {
        return true;
    }
    coverage C
    {
        return {TheOnlyBranch, "The only branch"};
    }
    post
    {
        /*
         * This call is equivalent to svcudp_bufcreate( sock, SZ, SZ) for some default
         * size SZ.
         */
        REQ("svcudp_create.01", "", TODO_REQ());

        return true;
    }
}

/********************************************************************/
/**                       Svc Types                                **/
/********************************************************************/

specification typedef struct SvcRunReturnType SvcRunReturnType = {};

SvcRunReturnType *create_SvcRunReturnType(
    CallContext context
    )
{
    return create(&type_SvcRunReturnType, context);
}

/********************************************************************/
/**                       Helper Functions                         **/
/********************************************************************/