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 */