distTLI/acceptcall.c

///////////////////////////////////////////////////////////////////////////////
// Filename: acceptcall.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: accept an incoming connection request
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/03/12 02:37:12 muellerg: created
//
///////////////////////////////////////////////////////////////////////////////


// Feature test switches ///////////////////////////// Feature test switches //
    /* NONE */


// System headers /////////////////////////////////////////// System headers //

#include <stdio.h>
#include <tiuser.h>
#include <fcntl.h>
#include <stropts.h>
#include <unistd.h>
#include <stdlib.h>


// Local headers ///////////////////////////////////////////// Local headers //

#include "../common.h"



// Macros /////////////////////////////////////////////////////////// Macros //
    /* NONE */



// File scope objects /////////////////////////////////// File scope objects //
    /* NONE */



// External variables, functions, and classes ///////////// External objects //
    /* NONE */



// Signal catching functions ///////////////////// Signal catching functions //
    /* NONE */



// Structures, unions, and class definitions /////////////////// Definitions //
    /* NONE */



// Functions and class implementation /// Functions and class implementation //

/*
 * Accept an incoming connection request.
 *
 * Return the new descriptor that refers to the newly accepted connection,
 * or -1.  The only time we return -1 is if a disconnect arrives before
 * the accept is performed.
 *
 *
 * in: listenfd: the descriptor caller used for t_listen() 
 *     callptr:  from t_listen(), passed to t_accept() 
 *     name:     name of transport provider 
 *     rwflag;   if nonzero, push read/write module 
 *
 * out: new descriptor
 */


int
accept_call(int listenfd, struct t_call *callptr, char *name, int rwflag)
{
    int     newfd;
    extern int  t_errno;


    // Open the transport provider to get a new file descriptor.

    if ( (newfd = t_open(name, O_RDWR, (struct t_info *) 0)) < 0)
        error.system("t_open error");


    // Bind any local address to the new descriptor.  Since this
    // function is intended to be called by a server after a
    // connection request has arrived, any local address will suffice.

    if (t_bind(newfd, (struct t_bind *) 0, (struct t_bind *) 0) < 0)
        error.system("t_bind error");


    // Accept the connection request on the new descriptor.

    if (t_accept(listenfd, newfd, callptr) < 0)
    {
        if (t_errno == TLOOK)
        {
            // An asynchronous event has occurred.  We must have
            // received a disconnect.  Go ahead and call t_rcvdis(),
            // then close the new file descriptor that we opened
            // above.

            if (t_rcvdis(listenfd, (struct t_discon *) 0) < 0)
                error.system("t_rcvdis error");
            if (t_close(newfd) < 0)
                error.system("t_close error");
            return(-1);     // return error to caller 
        }
        error.system("t_accept error");
    }


    // If the caller requests, push the streams module "tirdwr" onto
    // the new stream, so that the read(2) and write(2) system calls
    // can be used.  We first have to pop the "timod" module (the
    // default).

    if (rwflag)
    {
        if (ioctl(newfd, I_POP, (char *) 0) < 0)
            error.system("I_POP of timod failed");

        if (ioctl(newfd, I_PUSH, "tirdwr") < 0)
            error.system("I_PUSH of tirdwr failed");
    }

    return(newfd);
}


// Main /////////////////////////////////////////////////////////////// Main //
    /* NONE */