HP OpenVMS Systems Documentation

Content starts here

VMS DECwindows Transport Manual


Previous Contents Index

  1. If the $QIO failed and the reason was other than SS$_ENDOFFILE, cease processing.
  2. If the $QIO failed and the reason was SS$_ENDOFFILE, then the conversion request could not find the host name in the UCX host database. In this case, assume that the caller supplied the name of the node in Internet Standard Format (for example, 130.180.40.44).
    This is also the format of the result string returned by the GETHOSTBYNAME ACPCONTROL function, so continue as if the $QIO was successful and use the caller's node argument as the result of the ACPCONTROL $QIO system service.
  3. Call the PARSE_INTERNET_ADDRESS routine to convert the text address to a binary address.
  4. Determine which TCP port to attach to on the server side and place this port number, in Network Standard Format, in the sockaddrin structure. The port number is the result of adding the server number to 6000. (The server number is usually 0.)
  5. Address conversion was successful, so attempt to attach to the server. This is done by invoking the $QIO system service with an IO$_ACCESS function code. The P3 argument is the address of a descriptor of the sockaddrin structure that contains the address and port number of the server.
    If the $QIO completes successfully, the OPEN_AST3 AST routine continues the connection setup.
  6. Dismiss the executive-mode AST. The process will continue to wait in user mode.
  7. End of the named block CONNECT.
  8. An error occurred. Deassign the channel to UCX, remove the connection from the list of known connections, and call DECW$$XPORT_OPEN_COMPLETE to tell the common layer of the failure. The transport-common layer deallocates the user memory allocated by DECW$XPORT_ALLOC_INIT_QUEUES.

8.2.15 Sample OPEN_AST3 Routine

OPEN_AST3 is invoked in executive mode when the IO$_ACCESS $QIO issued by the OPEN_AST2 routine completes. OPEN_AST3 attempts to complete the connection to the workstation.

Example 8-15 shows a sample implementation of the OPEN_AST3 completion routine.

Example 8-15 Sample OPEN_AST3 Routine

   .
   .
   .
GLOBAL ROUTINE  OPEN_AST3( itcc : REF $BBLOCK ) : NOVALUE =

    BEGIN
    BUILTIN
        REMQUE ;

    BIND
        tcc = .itcc [ixtcc$a_tcc] : $BBLOCK,
        tpb = .itcc [ixtcc$a_tpb] : $BBLOCK ;

    LOCAL
        tcb,
        status;

    LABEL
        connect;

connect:
    (1)BEGIN
    status = .itcc [ixtcc$l_iosb] ;
    IF NOT .status
    THEN
        LEAVE connect ;


    (2)tcc [xtcc$l_flags]              = xtcc$m_active ;
    tcc [xtcc$v_mode]           = DECW$K_XPORT_REMOTE_CLIENT ;
    itcc [ixtcc$a_tdb]          = .tcpip_tdb ;
    itcc [ixtcc$w_efn]          = .tcpip_tdb [xtdb$w_efn] ;
    itcc [ixtcc$a_xport_table]  = .tcpip_tdb [xtdb$a_xport_table] ;


    (3)xport_in_state_srp( tcc ) ;
    xport_out_state_srp( tcc ) ;
    xport_in_free_disable( tcc, decw$c_xport_buffer_lrp ) ;


    (4)status = $REMQTI( .itcc [ixtcc$a_ifs_queue], tcb ) ;

    IF (.status EQL xport$k_queue_corrupted) OR
       (.status EQL xport$k_queue_no_entry)
    THEN
        BEGIN
        status = DECW$_BADQUEUE ;
        LEAVE connect ;
        END ;


    (5)xport_in_free_disable( tcc, decw$c_xport_buffer_srp ) ;
    status = DECW$$TCPIP_FREE_INPUT_BUFFER( .itcc, .tcb ) ;
    IF NOT .status
    THEN
        LEAVE connect ;


    (6)DECW$$XPORT_OPEN_COMPLETE( .itcc, .status );
    RETURN;

    (7)END;

    (8)$DASSGN( CHAN = .itcc [ixtcc$w_chan] ) ;

    REMQUE( .itcc, itcc ) ;
    tcpip_tdb [xtdb$l_ref_count] = .tcpip_tdb [xtdb$l_ref_count] - 1 ;

    DECW$$XPORT_OPEN_COMPLETE( .itcc, .status ) ;

    RETURN;
    END ;
   .
   .
   .
  1. Check the status of the IO$_ACCESS QIO initiated in OPEN_AST2. If it failed, exit the block named CONNECT.
  2. Mark the connection as active by setting the flags longword of the XTCC to the constant XTCC$M_ACTIVE and the connection mode as a remote client. These two operations should be performed in this order because the mode field is a subfield of the flags longword.
    Initialize the pointers to the XTDB in the IXTCC and the pointer to the transport function table in the IXTCC. Inherit the event flag for I/O operations from the XTDB.
  3. Force the input and output operations to use SRPs for startup and disable free-input operations on the input LRP free queue.
  4. Remove an XTCB from the tail of the small input free queue. If the queue was empty or corrupted, return a bad queue status and leave the block named connect.
  5. Disable free-input operations on the input SRP free queue. Call DECW$XPORT_FREE_INPUT_BUFFER to start the first read operation on the connection.
  6. Call DECW$$XPORT_OPEN_COMPLETE to return the status to the common layer. This is the successful end of the CONNECT code path. Dismiss the executive-mode AST. The process will continue in user mode.
  7. End of the block named CONNECT.
  8. This code is entered as a result of leaving the CONNECT code path due to some problem. Deassign the channel to UCX, remove the connection from the list of known connections, and call the transport common DECW$$XPORT_OPEN_COMPLETE routine with the failure status. The transport-common layer deallocates the user memory allocated by DECW$XPORT_ALLOC_INIT_QUEUES.

8.2.16 Sample XTFT$A_ATTACH_TRANSPORT Routine

The XTFT$A_ATTACH_TRANSPORT routine acts as an initialization procedure to perform any client- or server-specific operations required prior to establishing connections.

Example 8-16 shows a sample implementation of the XTFT$A_ATTACH_TRANSPORT routine.

Example 8-16 Sample XTFT$A_ATTACH_TRANSPORT Routine

     .
     .
     .
  GLOBAL ROUTINE DECW$$TCPIP_ATTACH_TRANSPORT(   tdb : REF $BBLOCK ) =

  BEGIN
  BIND
      iosb = tdb [xtdb$w_iosb] : VECTOR [4,WORD],
      xtpb = .tdb [xtdb$a_tpb] : $BBLOCK ;

  LABEL
      attach ;

  OWN
      socktype : INITIAL( (UCX$C_STREAM ^ 16) + UCX$C_TCP ),
      sockaddrin : $BBLOCK [SIN$S_SOCKADDRIN] PRESET(
          [SIN$W_FAMILY] = INET$C_AF_INET,
          [SIN$W_PORT]   = 0,
          [SIN$L_ADDR]   = swap_long( INET$C_INADDR_ANY ) ) ;

  LOCAL
      sin_desc : VECTOR [2] INITIAL( SIN$S_SOCKADDRIN, sockaddrin ),
      log_desc : $BBLOCK [DSC$S_DSCDEF1],
      tab_desc : $BBLOCK [DSC$S_DSCDEF1],
      items : BLOCKVECTOR [2, ITM$S_ITEM, 1],
      host_addr : VECTOR [16,BYTE,UNSIGNED],
      host_desc : VECTOR [2] INITIAL( %ALLOCATION( host_addr ) - 1, host_addr ),
      host_len : INITIAL( 0 ),
      func_code : INITIAL( INETACP_FUNC$C_GETHOSTBYNAME ),
      func_code_desc : VECTOR [2] INITIAL( %ALLOCATION( func_code ), func_code ),
      retlen,
      status ;

(1) inet_dev_desc [0] = %CHARCOUNT( inet_dev_str ) ;
   inet_dev_desc [1] = UPLIT( inet_dev_str ) ;

(2) tcpip_tdb = .tdb ;
   tdb [xtdb$w_efn] = ASYNC_EFN ;

(3) lnn_desc [DSC$A_POINTER] = local_node ;
   items [0,ITM$W_ITMCOD] = LNM$_STRING ;
   items [0,ITM$W_BUFSIZ] = %ALLOCATION( local_node ) ;
   items [0,ITM$L_BUFADR] = local_node ;
   items [0,ITM$L_RETLEN] = lnn_desc [DSC$W_LENGTH] ;
   items [1,ITM$W_ITMCOD] = 0 ;
   items [1,ITM$W_BUFSIZ] = 0 ;
   items [1,ITM$L_BUFADR] = 0 ;
   items [1,ITM$L_RETLEN] = 0 ;
   log_desc [DSC$W_LENGTH] = %CHARCOUNT( inet_local_node ) ;
   log_desc [DSC$B_DTYPE] = DSC$K_DTYPE_T ;
   log_desc [DSC$B_CLASS] = DSC$K_CLASS_S ;
   log_desc [DSC$A_POINTER] = UPLIT( inet_local_node ) ;
   tab_desc [DSC$W_LENGTH] = %CHARCOUNT( 'LNM$FILE_DEV' ) ;
   tab_desc [DSC$B_DTYPE] = DSC$K_DTYPE_T ;
   tab_desc [DSC$B_CLASS] = DSC$K_CLASS_S ;
   tab_desc [DSC$A_POINTER] = UPLIT( 'LNM$FILE_DEV' ) ;

   status = $TRNLNM( TABNAM = tab_desc,
                     LOGNAM = log_desc,
                     ITMLST = items ) ;

(4) IF ( .tdb [xtdb$v_mode] AND DECW$M_XPORT_CLIENT ) NEQ 0
   THEN
       RETURN .status ;

   attach:
        BEGIN
        IF NOT .status
        THEN
            LEAVE attach;

(5) IF NOT (status = $ASSIGN(   DEVNAM = inet_dev_desc,
                               CHAN = tdb [xtdb$w_chan],
                               ACMODE = psl$c_user ) )
   THEN
       LEAVE attach ;

(6) IF (status = $qiow(         EFN = .tdb [xtdb$w_efn],
                               CHAN = .tdb [xtdb$w_chan],
                               FUNC = IO$_ACPCONTROL,
                               IOSB = iosb,
                               P1 = func_code_desc,
                               P2 = lnn_desc,
                               P3 = host_len,
                               P4 = host_desc ) )
   THEN
       status = .iosb [0] ;
   IF NOT .status
   THEN
       LEAVE attach ;


   host_desc [0] = .host_len ;
(7) status = parse_internet_address( host_desc, sockaddrin [SIN$L_ADDR] ) ;
   IF NOT .status
   THEN
       LEAVE attach ;

(8) sockaddrin [SIN$W_PORT] = swap_short( ( BASE_TCP_PORT +
                                            .xtpb [xtpb$w_display_num] ) ) ;

(9) IF (status = $QIOW(      EFN = .tdb [xtdb$w_efn],
                            CHAN = .tdb [xtdb$w_chan],
                            FUNC = IO$_SETMODE,
                            IOSB = iosb,
                            P1 = socktype,
                            P2 = ( %X'01000000' OR INET$M_LINGER OR INET$M_KEEPALIVE ),
                            P3 = sin_desc,
                            P4 = 5 ) )
   THEN
       status = .iosb [0] ;
   IF NOT .status
   THEN
       LEAVE attach ;

(10) IF NOT ( status = transport_read_queue( .tdb ) )
   THEN
       LEAVE attach ;

(11) DECW$XPORT_ATTACHED( .tdb ) ;
   reattach_timer_id = 0 ;
   RETURN SS$_NORMAL ;
   END ;

(12) detach_and_poll( .tdb ) ;
   RETURN .status ;
   END ;
     .
     .
     .
  1. Create a suitable descriptor for the Internet device logical name string. The .address directive that would result from doing this at compile time cannot be fixed up by the image activator, so the descriptor is created at run time.
  2. Store the address of the XTDB that the common transport allocated for this transport in tcpip_tdb. References to this XTDB by the TCP/IP transport are usually made through this variable. Use event flag 31 (ASYNC_EFN) in asynchronous transport operations.
  3. Get the string that represents the local system name in the Internet name space by translating the logical name UCX$INET_HOST that is generated by the local_node macro.
  4. If the transport is being attached by a client, no additional work is needed. A server continues processing to create a listener socket, among other things.
  5. Create a socket and assign a channel to the Internet networking service. This socket is owned by the specific transport and becomes the listener socket for all connection requests received from clients.
  6. Attempt to perform a name-to-address conversion for the local node with an IO$_ACPCONTROL $QIO system service that queries the UCX host database. The $QIO arguments are as follows:
    • The P1 argument specifies the control function that, in this case, requests a get-host-by-name conversion. P1 is the function to be performed by the IO$_ACPCONTROL $QIO.
    • P2 is the address of the descriptor of the local node name acquired at the beginning of this procedure.
    • P3 is the address of a word to receive the length of the returned address string.
    • P4 is the address of the descriptor of the storage to receive the address found by the search.
  7. Call the PARSE_INTERNET_ADDRESS routine to convert the ASCII Internet Standard Format address returned by the ACPCONTROL $QIO into the binary, 32-bit Network Standard Format address. (See Example 8-12.)
  8. If the conversion is successful, the Network Standard Format address is built in the sockaddrin structure. Determine which TCP port number to use to listen for client connection requests. Place this port number, in Network Standard Format, in the sockaddrin structure. (The port number is the result of adding the server number to 6000.)
  9. Establish the local address, port number, address family, and socket options on the listener socket. The $QIO arguments are as follows:
    • The P1 argument of the IO$_SETMODE $QIO system service is the address of a longword containing the protocol family and type to use (stream-mode, TCP socket).
    • The P2 argument sets various options for the socket (in this case, the linger and keep-alive TCP options).
    • The P3 argument is the address of a descriptor of the sockaddrin structure that contains the address information for the socket.
    • The P5 argument is a nonzero value (specifically, 5) that marks the socket as a listener and sets the size of the connect queue. The connect queue limits the number of unacknowledged client connect requests that the Internet networking service is willing to retain.
  10. Invoke the TRANSPORT_READ_QUEUE routine to start an asynchronous socket-accept operation. At this point, the server is capable of receiving connection requests from clients.
  11. Call DECW$XPORT_ATTACHED to report that the transport is attached.
  12. This code is entered only if something went wrong. Call the DETACH_AND_POLL routine to deassign any channels and attempt to reattach to the network.

8.2.17 Sample TRANSPORT_READ_QUEUE Routine

The TRANSPORT_READ_QUEUE routine initiates an asynchronous connect-accept operation on the listener socket. Example 8-17 shows a sample implementation of the TRANSPORT_READ_QUEUE routine.

Example 8-17 Sample TRANSPORT_READ_QUEUE Routine

   .
   .
   .
ROUTINE transport_read_queue( tdb : REF $BBLOCK ) =

BEGIN

LOCAL
    item3 : VECTOR [3],
    status ;

(1)IF NOT .tdb [xtdb$v_dying]
THEN
    BEGIN

    (2)IF NOT (status = $ASSIGN(       DEVNAM = inet_dev_desc,
                                    CHAN = tdb [xtdb$w_acc_chan],
                                    ACMODE = psl$c_user ) )
    THEN
        BEGIN
        tdb [xtdb$v_dying] = 1 ;
        RETURN .status
        END ;

    (3)item3 [0] = xtdb$s_acc_inaddr ;
    item3 [1] = tdb [xtdb$t_acc_inaddr] ;
    item3 [2] = tdb [xtdb$l_acc_inaddr_len] ;
    (4)status = $qio(  EFN = .tdb [xtdb$w_efn],
                    CHAN = .tdb [xtdb$w_chan],
                    FUNC = IO$_ACCESS OR IO$M_ACCEPT,
                    IOSB = tdb [xtdb$w_acc_iosb],
                    ASTADR = transport_read_ast,
                    ASTPRM = .tdb,
                    P3 = item3,
                    P4 = tdb [xtdb$w_acc_chan] ) ;
    IF NOT .status
    THEN
        BEGIN
        $DASSGN(   CHAN = .tdb [xtdb$w_acc_chan] ) ;
        tdb [xtdb$v_dying] = 1 ;
        END
    END
ELSE
    status = DECW$_CNXABORT ;

RETURN .status ;

END ;
   .
   .
   .
  1. If the transport is dying, do not try to start another accept operation.
  2. Create a socket and assign a channel to the Internet networking service. If $ASSIGN fails, mark the transport as dying and quit. If successful, the channel number is stored in the XTDB$W_ACC_CHAN field of the XTDB, which is a field specific to this transport.
  3. Create an item-list structure describing the area that is to receive information about the client that attempts to connect to the server. The first longword is the size of the area in bytes, the second is the address of the first byte, and the third is the address of a longword to receive the length of the data actually placed in the area.
    The item-list structure is allocated as a 16-byte field, XTDB$T_ACC_INADDR, in the XTDB. XTDB$S_ACC_INADDR is the symbolic name for the length.
  4. Initiate an asychronous accept operation on the listener socket by means of the $QIO system service. The $QIO arguments are as follows:
    • The CHAN argument is the channel associated with the listener socket created in the XTFT$A_ATTACH_TRANSPORT routine. The specific transport uses this channel for connection requests from all clients.
    • The FUNC argument code is IO$_ACCESS with the IO$M_ACCEPT modifier specified.
    • The ASTADR argument is the AST completion routine to invoke on completion. TRANSPORT_READ_AST, which is described in Section 8.2.18, expects the address of the TCP/IP XTDB as its argument.
    • The P3 argument is the address of the 3-longword item list previously described. The item list is used to store information about the connecting client's node.
    • The P4 argument is the channel associated with the socket created on entry to TRANSPORT_READ_QUEUE. The server will use this channel for communication with the client. Each client connection is assigned its own channel.

    If the $QIO service failed, mark the transport as dying and release the channel.

8.2.18 Sample TRANSPORT_READ_AST Routine

TRANSPORT_READ_AST is invoked when the IO$_ACCESS $QIO issued by the TRANSPORT_READ_QUEUE routine completes and continues processing to fully establish the client connection.

Example 8-18 shows a sample implementation of the TRANSPORT_READ_AST routine.

Example 8-18 Sample TRANSPORT_READ_AST Routine

   .
   .
   .
ROUTINE transport_read_ast( tdb : REF $BBLOCK ) : NOVALUE =

BEGIN
BUILTIN
    REMQUE,
    INSQTI,
    INSQUE ;
BIND
    xtpb = .tcpip_tdb [xtdb$a_tpb] : $BBLOCK,
    acc_iosb = tcpip_tdb [xtdb$w_acc_iosb] : VECTOR [4,WORD,UNSIGNED] ;

LOCAL
    psl : $BBLOCK [4],
    found : INITIAL( 0 ),
    iosb : VECTOR [4,WORD,UNSIGNED] ;

(1)IF .acc_iosb [0] EQL SS$_SHUT
THEN
    BEGIN
    DECW$XPORT_ATTACH_LOST( .tdb , 0 ) ;
    detach_and_poll( .tdb ) ;
    RETURN ;
    END ;

IF .acc_iosb [0]
THEN

    BEGIN
    MACRO
        ctrstr = '!UB.!UB.!UB.!UB' % ;

    LOCAL
        tcq : REF $BBLOCK INITIAL( 0 ),
        tcc : REF $BBLOCK INITIAL( 0 ),
        itcc : REF $BBLOCK INITIAL( 0 ),
        tcc_id : INITIAL( 0 ),
        tpb : REF $BBLOCK INITIAL( 0 ),
        fail : INITIAL( 1 ),
        status,
        il_count : INITIAL( .xtpb [xtpb$w_i_lrp_count] ),
        is_count : INITIAL( .xtpb [xtpb$w_i_srp_count] ),
        ol_count : INITIAL( .xtpb [xtpb$w_o_lrp_count] ),
        os_count : INITIAL( .xtpb [xtpb$w_o_srp_count] ),
        at_tcb,
        tcb_count,
        tcb_array : REF VECTOR [] INITIAL( 0 ),
        func_code : INITIAL( INETACP_FUNC$C_GETHOSTBYADDR ),
        func_code_desc : VECTOR [2] INITIAL( %ALLOCATION( func_code ),
                                              func_code ),
        inaddr : $BBLOCK [16],
        inaddr_len,
        inaddr_desc : VECTOR [2] INITIAL( %ALLOCATION( inaddr ), inaddr ),
        client_desc : VECTOR [2],
        ctr_desc : VECTOR [2] INITIAL( %CHARCOUNT( ctrstr ),
                                                       UPLIT( ctrstr ) ),
        info_size,
        info_ptr,
        client_len ;

    LABEL
        connect ;

    (2)connect:    BEGIN

        info_size = INET_NODE_NAME_LEN ;
        (3)IF (itcc = DECW$XPORT_ALLOC_PMEM( ixtcc$c_tcpip_length,
                                              DECW$C_DYN_IXTCC )) EQLA 0
        THEN
            BEGIN
            status = SS$_INSFMEM ;
            LEAVE connect ;
            END


        (4)tcpip_tdb [xtdb$l_ref_count]    = .tcpip_tdb [xtdb$l_ref_count] + 1 ;
        INSQUE( .itcc, tcpip_tdb [xtdb$a_itcc_flink] ) ;

        IF (tpb = DECW$XPORT_ALLOC_PMEM( xtpb$c_tcpip_length,
                                         DECW$C_DYN_XTPB )) EQLA 0
        THEN
            BEGIN
            status = SS$_INSFMEM ;
            LEAVE connect ;
            END

         CH$MOVE( xtpb$c_tcpip_length, .tcpip_tdb [xtdb$a_tpb], .tpb )
         itcc [ixtcc$a_tpb] = .tpb ;

         (5)status = DECW$XPORT_ALLOC_INIT_QUEUES( .itcc,
                  .tcpip_tft[xtft$l_xtcc_length],
                  .tpb [xtpb$w_srp_size],
                  .tpb [xtpb$w_lrp_size],
                  .tpb [xtpb$w_i_srp_count],
                  .tpb [xtpb$w_i_lrp_count],
                  .tpb [xtpb$w_o_srp_count],
                  .tpb [xtpb$w_o_lrp_count],
                  .info_size,
                  info_ptr) ;

         IF NOT .status
         THEN
             LEAVE connect ;

         tcc = .itcc[ixtcc$a_tcc] ;

         inaddr_len = 0 ;
         (6)IF NOT (status = $FAO(  ctr_desc,
                                 inaddr_len,
                                 inaddr_desc,
                                 .(tdb [xtdb$t_acc_inaddr])<32,8,0>,
                                 .(tdb [xtdb$t_acc_inaddr])<40,8,0>,
                                 .(tdb [xtdb$t_acc_inaddr])<48,8,0>,
                                 .(tdb [xtdb$t_acc_inaddr])<56,8,0> ) )
         THEN
             BEGIN
             LEAVE connect ;
             END ;

         inaddr_desc [0] = .inaddr_len ;
         client_desc [0] = INET_NODE_NAME_LEN - 1 ;
         client_desc [1] = .info_ptr + 1 ;
         client_len = 0 ;

         (7)IF (status = $QIOW( EFN = .tdb [xtdb$w_efn],
                                 CHAN = .tdb [xtdb$w_chan],
                                 FUNC = IO$_ACPCONTROL,
                                 IOSB = iosb,
                                 P1 = func_code_desc,
                                 P2 = inaddr_desc,
                                 P3 = client_len,
                                 P4 = client_desc ) )
         THEN
             status = .iosb [0] ;
         IF NOT .status
         THEN
             BEGIN
             IF .status NEQU SS$_ENDOFFILE
             THEN
                 BEGIN
                 LEAVE connect ;
                 END
             (8)ELSE
                 BEGIN

                 CH$MOVE( .inaddr_len, .inaddr_desc [1], .client_desc [1] ) ;
                 client_desc [0] = .inaddr_len ;
                 client_len = .inaddr_len ;
                 END ;
             END
         (9)ELSE
             BEGIN
             IF CH$EQL( .client_len, .client_desc [1], .lnn_desc [DSC$W_LENGTH],
                        .lnn_desc [DSC$A_POINTER], %C' ' )
             THEN
                 BEGIN
                 (.client_desc [1])<0,8,0> = %C'0' ;
                 client_desc [0] = 1 ;
                 client_len = 1 ;
                 END ;
             END ;
     (10)
         (.info_ptr)<0,8,0> = %C'?' ;

         (11)IF .info_size GTR 0
         THEN
             BEGIN
             tcc [xtcc$a_rem_user]         = .info_ptr ;
             tcc [xtcc$l_rem_user_len]     = 1 ;
             tcc [xtcc$a_rem_node]         = .info_ptr + 1 ;
             tcc [xtcc$l_rem_node_len]     = .client_len ;
             END ;


         (12)itcc [ixtcc$w_chan]           = .tcpip_tdb [xtdb$w_acc_chan] ;
         tcpip_tdb [xtdb$w_acc_chan]   = 0 ;

         (13)tcc [xtcc$l_flags]            = xtcc$m_active ;
         tcc [xtcc$v_mode]             = DECW$K_XPORT_REMOTE_SERVER ;
         itcc [ixtcc$w_efn]            = .tcpip_tdb [xtdb$w_efn] ;
         itcc [ixtcc$a_tdb]            = .tcpip_tdb ;
         itcc [ixtcc$a_xport_table]    = .tcpip_tdb [xtdb$a_xport_table] ;

         (14)IF NOT (status = $DCLAST(   ASTADR = transport_open_callback,
                                     ASTPRM = .itcc,
                                     ACMODE = psl$c_user ) )
         THEN
             LEAVE connect ;
         (15)fail = 0 ;
         END ;

    (16)IF .fail
    THEN
        (17)BEGIN
        IF .itcc NEQA 0
        THEN
            BEGIN
            IF .itcc [ixtcc$w_chan] NEQU 0
            THEN
                $DASSGN( CHAN = .itcc [ixtcc$w_chan] ) ;
            REMQUE( .itcc, itcc ) ;
            tcpip_tdb [xtdb$l_ref_count] = .tcpip_tdb [xtdb$l_ref_count] - 1 ;
            DECW$XPORT_DEALLOC_QUEUES( .itcc ) ;
            DECW$XPORT_DEALLOC_PMEM( .itcc ) ;
            END ;
        IF .tpb NEQA 0
        THEN
            DECW$XPORT_DEALLOC_PMEM( .tpb ) ;

        DECW$XPORT_ACCEPT_FAILED (  .tcpip_tdb [xtdb$l_acc_inaddr_len],
                                    tcpip_tdb [xtdb$t_acc_inaddr],
                                    .status ) ;
        END ;
    END ;

(18)transport_read_queue( .tcpip_tdb ) ;

END ;
   .
   .
   .


Previous Next Contents Index