# DIGITAL TCP/IP Services for OpenVMS
System Services and C Socket Programming

Previous | Contents

The equivalent C Socket calls are the bind() and listen() routines.

## Format

> ### SYS$QIO [efn],chan,func, [iosb],[astadr],[astprm],[p1], [p2],[p3],[p4],[p5], [p6]

## Returns

> OpenVMS usage: | longword (unsigned)
> type: | write only
> access: | by value
> mechanism: | 0

Longword condition value. All system services return (by immediate value) a condition value in R0.

## ARGUMENTS

> ### efn

> OpenVMS usage: | ef_number
> type: | longword (unsigned)
> access: | read only
> mechanism: | by value

> Event flag that $QIO sets when the I/O operation is completed. The efn argument is a longword value containing the number of the event flag.

> If efn is not specified, event flag 0 is set.

> The specified event flag is set if the service terminates without queuing an I/O request.

> ### chan

> OpenVMS usage: | channel
> type: | word (unsigned)
> access: | read only
> mechanism: | by value

> I/O channel that is assigned to the device to which the request is directed. The chan argument is a word value containing the number of the I/O channel.

> ### func

> OpenVMS usage: | function_code
> type: | word (unsigned)
> access: | read only
> mechanism: | by value

> Function codes and function modifiers specify the operation of the software. The func argument is a longword value containing the function code.

> Refer to the Section 4.2 for complete information about the function codes and function modifiers.

> ### iosb

> OpenVMS usage: | io_status_block
> type: | quadword (unsigned)
> access: | write only
> mechanism: | by reference

> I/O status block to receive the final completion status of the I/O operation. The iosb is the address of the quadword I/O status block. See Figure 3-1 for a description of the general structure of the I/O status block.

> When the $QIO begins executing, the event flag clears. The $QIO also clears the quadword I/O status block if the iosb argument is specified.

> Although the iosb argument is optional, DIGITAL strongly recommends that you specify it for the following reasons:

> - If you are using an event flag to signal the completion of the service, you can test the I/O status block for a condition value. This assures that the event flag was not set by an event other than service completion.
> - If you are using the OpenVMS $SYNCH service to synchronize service completion, the I/O status block is a required argument for $SYNCH.
> - The condition values returned in the R0 and those returned in the I/O status block provide information about different aspects of the call to the $QIO service. The condition value returned in R0 gives you information about the success or failure of the service call itself. The condition values returned in the I/O status block report the success or failure of the service operation. Therefore, to access the success or failure of the $QIO call, check the condition values returned in both the R0 and the I/O status block.

> ### astadr

> OpenVMS usage: | ast_procedure
> type: | procedure entry mask
> access: | call without stack unwinding
> mechanism: | by reference

> AST service routine to be executed when the I/O is completed. The astadr argument is the address of the entry mask to the AST routine.

> The AST routine executes at the access mode of the caller of $QIO.

> ### astprm

> OpenVMS usage: | user_arg
> type: | longword (unsigned)
> access: | read only
> mechanism: | by value

> AST parameter to be passed to the AST service routine. The astprm argument is a longword value of the AST parameter.

> ### p1 to p6

> OpenVMS usage: | varying_arg
> type: | longword (unsigned)
> access: | read only
> mechanism: | by reference, by value, or descriptor

> Optional device- and function-specific I/O request arguments. The parameter values contained in these arguments vary according to the function for which they are used. See Table 4-5 for the descriptions of internet I/O function codes.

## DESCRIPTION

> $QIO operates only on assigned I/O channels and only from access modes that are equal to or more privileged than the access mode from which the original channel assignment was made.

> For TCP/IP, $QIO uses the following system resources:

> - The process's AST limit (ASTLM) quota, if an AST service routine is specified.
> - System dynamic memory, which is required to queue the I/O request. System dynamic memory requirements are protocol specific.
> - Additional memory may be required on a device-dependent basis.

> For $QIO, completion can be synchronized as follows:

> - By specifying the astadr argument to have an AST routine execute when the I/O is completed.
> - By calling the $SYNCH Synchronize service to await completion of the I/O operation. (If you want your I/O operation to complete synchronously, use the $QIOW system service instead.)

## Condition Values Returned

> Each function used with$QIO has its own error codes. See the error codes listed under the individual internet I/O function code descriptions that comprise the remainder of this chapter.

# 4.2 Internet I/O Function Codes

The internet pseudodevice allows physical, logical, and virtual block I/O functions. The physical and logical functions are used only with the IP layer. Table 4-5 lists the basic functions and their modifiers. The sections that follow describe these functions in greater detail.

Table 4-5 Internet I/O Function Codes
Function Code and Arguments | Function Modifier | Description
--- | --- | ---
IO$_ACCESS p3,p4 | IO$M_ACCEPT | Open a connection.
IO$_ACPCONTROL p1 |  | Perform an ACP (ancillary control process) operation.
IO$_DEACCESS p4 | IO$M_SHUTDOWN | Abort or close a connection.
IO$_READVBLK p1,p2,p3,p4,p6 | IO$M_INTERRUPT | Read virtual block.
| IO$M_PURGE IO$M_LOCKBUF | Control the buffer operations.
IO$_SENSEMODE [ p2], p3,p4,p6 |  | Read the internet pseudodevice characteristics.
IO$_SENSECHAR [ p2], p3,p4,p6 |  | Read the internet pseudodevice characteristics.
IO$_SETMODE p1,[ p2], p3,p4,p5 | IO$M_OUTBAND IO$M_READATTN IO$M_WRTATTN | Set the internet pseudodevice characteristics for subsequent operations.
IO$_SETCHAR p1,[ p2], p3,p4,p5 | IO$M_OUTBAND IO$M_READATTN IO$M_WRTEATTN | Set the internet pseudodevice characteristics for subsequent operations.
IO$_WRITEVBLK p1,p2,p3,p4,p5 | IO$M_INTERRUPT | Write virtual block.

Table 3-2 contains the file names of the symbol definition files. These files specify $QIO arguments (p1,p2,...p6) for applications written in the corresponding programming languages. You must invoke the symbol definition by using the appropriate include statement in your application.

# IO$_ACCESS

> When you are using a connection-oriented protocol such as TCP, the IO$_ACCESS function initiates a connection and specifies a remote port and address. When you use a connectionless protocol such as UDP, the IO$_ACCESS function sets the remote port and address.

> For TCP, a connection request times out in a specified interval (75 seconds by default). This interval can be changed by the system manager. The program can also set a specific timeout interval for a socket that it has created.

> The equivalent C Socket function is connect() or accept().

## ARGUMENTS

> ### p3

> UCX usage | remote socket name
> type | longword (unsigned)
> access | read only
> mechanism | by descriptor

> For the IO$_ACCESS function, the p3 parameter is the address of a UCX item_list_2 descriptor that points to the sockaddr_in structure containing the remote host address and port number.

> For the IO$_ACCESS function with the IO$M_ACCEPT modifier, the p3 parameter is the address of a UCX item_list_3 descriptor that points to a socket name and a returned longword that contains the length.

> ### p4

> UCX usage | the device channel
> type | word (unsigned)
> access | read only
> mechanism | by reference

> The p4 parameter specifies the address of a word value containing the channel for the I/O operations after the connection is established. This input parameter is specified only with the IO$M_ACCEPT modifier (for TCP).

## Function Modifiers

> IO$M_ACCEPT | Accepts a connection request issued from another process. The remote host address and remote port number are output parameters.
> IO$M_NOW | Regardless of a $QIO or $QIOW, if the system detects a condition that would cause the I/O operation to block, the system completes the I/O operation and returns the $QIO error code SS$_SUSPENDED. The corresponding UNIX error code is EWOULDBLOCK.

## Condition Values Returned

> SS$_ABORT | Programming error, INET management error, or hardware error. Aborts execution of the I/O operation.
> SS$_BADPARAM | Programming error that occurred for one of the following reasons: You tried to execute a $QIO function without specifying a device socket. You tried to issue an IO$_ACCESS!IO$M_ACCEPT function without specifying the channel for the device socket that will be used for the accepted connection ( p4 is null or invalid). You tried to issue an IO$_ACCESS function without specifying the address of the remote device socket address ( p3 as null).
> SS$_BUGCHECK | Inconsistent state. Report the problem to your DIGITAL support representative.
> SS$_CANCEL | Warning code. The I/O operation was canceled by a $CANCEL system service.
> SS$_CONNECFAIL | Programming error, INET management error, or hardware error. The connection was abnormally terminated for one of the following reasons: An IO$_ACCESS!IO$M_ACCEPT failed because the listener socket closed. The cause can be local or remote. An existing connection was aborted because of an error detected during communication.
> SS$_DEVINACT | Programming or INET management error. The driver was not started. Issue a UCX START COMMUNICATION command before issuing any $QIO call.
> SS$_DEVNOTMOUNT | Programming or INET management error. You improperly executed the INET startup procedure. The driver was loaded, but the INET_ACP was not activated.
> SS$_EXQUOTA | Programming or system management error. Socket quota (maximum number of sockets allowed) or user quotas exceeded.
> SS$_FILALRACC | Programming error. The socket name is already in use by one of the following: On a raw socket, you specified a remote INET socket address with an IO$_ACCESS function, but an INET address was already specified with a previous IO$_ACCESS. On a datagram, you specified a remote INET socket address with an IO$_ACCESS function, but an INET address was already specified with a previous IO$_ACCESS. On a stream socket, you issued an IO$_ACCESS function on a stream socket that was already connected.
> SS$_ILLCNTRFUNC | Programming error. Illegal function.
> SS$_INSFMEM | INET management or programming error. Not enough buffer space for allocation. The INET software needs more buffer space.
> SS$_IVADDR | Programming error. The specified INET address was not found or an invalid port and INET address combination was specified with the IO$_ACCESS function. Port zero is not allowed with an IO$_ACCESS function.
> SS$_IVBUFLEN | Programming error. Socket address buffer has an invalid size.
> SS$_NOLICENSE | Programming or system management error. DIGITAL TCP/IP for OpenVMS license is not present.
> SS$_NOLINKS | Programming error. An attempt was made to disconnect a socket that has not been connected.
> SS$_LINKABORT | Communication status change. The remote socket closed a connection.
> SS$_PROTOCOL | Programming error. The address family of the remote INET address specified with an IO$_ACCESS function is not supported (UDP/IP or TCP/IP). The address family should be UCX$C_AF_INET.
> SS$_REJECT | Programming error, INET management error, or hardware error. Connection is rejected for one of the following reasons: An attempt was made to connect to a remote socket that is already connected. An error was encountered while establishing the connection. The peer socket either refused a connection request or wants to close the connection.
> SS$_SHUT | The network is being shut down.
> SS$_SUSPENDED | The operation is blocked. The accept operation cannot complete because there are no connection requests received. The socket is marked as nonblocking.
> SS$_TIMEOUT | Programming error, INET management error, or hardware error. A TCP/IP connection timed out while in the process of being established. The default time interval is 75 seconds.
> SS$_UNREACHABLE | Communication status. Remote host or network is not reachable.

# IO$_ACPCONTROL

> The internet ACP Control I/O (IO$_ACPCONTROL) function requests that the ACP perform operations such as providing information from the internet host and network database files.

> The equivalent C Socket functions are gethostbyname(), gethostbyaddr(), getnetbyname(), or getnetbyaddr(). Two programming examples for the IO$_ACPCONTROL routine follow this command description. Example 4_7 uses the MACRO_32 programming language and Example 4-8 uses the C programming language.

## ARGUMENTS

> ### p1

> UCX usage | subfunction code
> type | longword (unsigned)
> access | read only
> mechanism | by descriptor

> The p1 parameter is the address of the OpenVMS descriptor for a 4-byte block. The block consists of a subfunction type (1 byte), a call code (1 byte), and 2 bytes reserved for DIGITAL (must be zero).

> Table 4-6 lists the valid INET subfunction codes. These symbols are defined by the $INETACPFSYMDEF module in the UCX$INETDEF symbol definition file.

> Table 4-6 Valid INET Subfunction Codes
> INET Subfunction Code | Code Function
> --- | ---
> INETACP_FUNC$C_GETHOSTBYNAME | Get the INET address of the specified host from the internet host database.
> INETACP_FUNC$C_GETHOSTBYADDR | Get the host name of the specified internet address from the internet host database.
> INETACP_FUNC$C_GETNETBYNAME | Get the INET address of the specified network from the internet network database.
> INETACP_FUNC$C_GETNETBYADDR | Get the network name of the specified internet address from the internet network database.

> When these functions are performed, IO$_ACPCONTROL searches the local database for the host's name. If it does not find the host name in the local host database, IO$_ACPCONTROL then searches the BIND database if the BIND resolver is enabled.

> Table 4-7 lists the valid INET call codes that IO$_ACPCONTROL accepts.

> Table 4-7 INET Call Codes
> Code | Description
> --- | ---
> INETACP$C_ALIASES | Obtains the list of alias names associated with the specified host or network from the internet hosts or network database.
> INETACP$C_TRANS | Returns a longword value of the internet address in dotted-decimal notation.
> INETACPC$C_HOSTENT_OFFSET | Returns full host information in a modified hostent structure. In the modified structure, pointers are replaced with offsets from the beginning of the structure.
> INETACP$C_NETENT_OFFSET | Returns full network information in a modified netent structure. In the modified structure, pointers are replaced with offsets from the beginning of the structure.

> The INET_ACP call codes are defined by the $INETACPSYMDEF module in the UCX$INETDEF symbol definition file.

> The hostent and netent structures are defined by the $HOSTENTDEF and $NETENTDEF modules in the UCX$INETDEF symbol definition file.

> ### p2

> UCX usage | input parameter
> type | longword (unsigned)
> access | read only
> mechanism | by descriptor

> The p2 parameter is the address of the string descriptor for the input parameter. The input parameter contains the host name, network name, host address, or network INET address. The INET address is specified as a character string. The network and host numbers are separated by periods. The address is in network format. For example, in the address 128.20.10.5, the network is 128.20.10 and the host is 5.

> ### p3

> UCX usage | length of the output string
> type | word
> access | write only
> mechanism | by reference

> The p3 parameter is the address of the word location where the length of the output string is returned.

> ### p4

> UCX usage | output character string address
> type | longword or character string
> access | write only
> mechanism | by descriptor

> The p4 parameter is the address of the descriptor for the output character string that contains the host name, network name, host address, or the network INET address. The INET address is returned as a character string. The network and host numbers are separated by periods. The address is in dotted decimal notation.

> Alias names are separated by a null character (a 0 byte). The length of the returned string includes all null characters that separate aliases.

## Condition Values Returned

> SS$_ABORT | Unknown cause of an internal error. An unspecified error was detected while performing an INET ACP function.
> SS$_BADPARAM | Programming or internal error. You specified a bad parameter (name or address) in a GET{HOST,NET}BY{NAME,ADDRESS} ACP call.
> SS$_BUFFEROVF | Programming error. There was not enough space for returning all alias names in a GET{HOST,NET}BY{NAME,ADDRESS} ACP call.
> SS$_ENDOFFILE | The information requested is not in the database.
> SS$_ILLCNTRFUNC | Programming error. An invalid ACP function code was specified in an IO$_ACPCONTROL function.
> SS$_NOPRIV | INET management error. No privilege for the execution of an INET ACP function.
> SS$_RESULTOVF | Programming error. The ACP overflowed the buffer in returning a parameter.
> SS$_SHUT | The network is being shut down.

Example 4-7 IO$_ACPCONTROL Function (MACRO-32 Programming)

            .title Get_host_by_name
            .ident  /01/
            .library        /sys$share:lib.mlb/
            .show meb

            $inetacpfdef

    dev:    .ascid  /ucx$device:/
    chan:   .long   0
    iosb:    .quad  0
    command:        .long   length
                    .address        comm
    comm:   .byte   1       ; get host
            .byte   0
            .word   0
    length=.-comm
    host_d: .ascid  /BRIGIT/
    host_nam: .ascid        /
            .blkl   32
    title:  .ascid /Host address:/
    title1: .ascid /Host name:/
            .entry   start,^m<>
    ;
    ; assign Internet device for INIT
    ;
            $assign_s       devnam=dev, chan=chan
            blbs    r0,as1
            brw     exit
    as1:
            $qioW_s efn=#1,-
                    chan=chan, -
                    func=#io$_acpcontrol,-
                    iosb= iosb,-
                    p1=command,p2=#host_d,P3=#host_nam,p4=#host_nam
            blbc    r0,print
            cmpw    #ss$_normal,iosb
            beqlu   print
            movzwl  iosb,r0
    print:
            movl    r0,r10
            pushab  title1
            calls   #1,g^lib$put_output
            pushab  host_d
            calls   #1,g^lib$put_output
            pushab  title
            calls   #1,g^lib$put_output
            pushab  host_nam
            calls   #1,g^lib$put_output
            movl    r10,r0
    exit:
            ret
            .end start

Example 4-8 IO$_ACPCONTROL Function (C Programming)

    #module gethost_addr
    /*
    **++
    **
    **  This example gets host address for the given host name
    **  using the Internet ACP Control I/O function IO$_ACPCONTROL
    **
    **
    **--
    **/

    /*
    **  INCLUDE FILES
    */

    #include <descrip.h>
    #include <iodef.h>
    #include <ucx$inetdef.h>

    gethost_addr (addr)

      int *addr;

    {

    /* Descriptor for Inet device name */

    struct dsc$descriptor Inet_dev =
      {11, DSC$K_CLASS_S, DSC$K_DTYPE_T, "UCX$DEVICE:" };

    /* Descriptor for the host name for which to get the Internet address */

    struct dsc$descriptor host_name =
      {6, DSC$K_CLASS_S, DSC$K_DTYPE_T, "lassie" };

    /* Descriptor for ACP command */

    struct dsc$descriptor command =
      {0, DSC$K_CLASS_S, DSC$K_DTYPE_T, 0 };

    /* Descriptor for host address */

    struct dsc$descriptor host_ad =
      {0, DSC$K_CLASS_S, DSC$K_DTYPE_T, 0 };

      int status ;            /* Return status                 */
      int iosb [2] ;          /* I/O status block              */
      short channel ;         /* INET dev channel              */
      short retlen ;          /* Word to return address length */

    /*
    ** ACP command: INETACP$C_TRANS - If this bit set, the Internet
    ** address will be returned as a long word integer value.
    ** INETACP_FUNC$C_GETHOSTBYNAME indicates that it is a function
    ** to get the host address given the host name.
    */
      int comm = INETACP$C_TRANS * 256 + INETACP_FUNC$C_GETHOSTBYNAME ;
                    /* byte 1,2,0,0 */

       int addr_buff[8];      /* buffer for ACP output */

    /*
    ** INET ACP command
    */
            command.dsc$a_pointer = &comm ;
            command.dsc$w_length = sizeof(comm) ;

    /*
    ** Descriptor for ACP output
    */
            host_ad.dsc$a_pointer = &addr_buff ;
            host_ad.dsc$w_length = sizeof(addr_buff) ;

    /*
    **  Assign a channel to INET  device
    */
            status = SYS$ASSIGN(&Inet_dev,
                                &channel,
                                0,
                                0);
            if ((status & 1) == 0) {
            printf("Failed to assign channel to INET device \n");
            return(status);
            }

    /*
    ** Get the Host address (longword)
    */
            status = SYS$QIOW(1,
                              channel,          /* Channel number */
                              IO$_ACPCONTROL,   /* I/O function */
                              iosb,             /* I/O status */
                              0,
                              0,
                              &command,         /* P1  command */
                              &host_name,       /* P2  host name */
                              &retlen,          /* P3  adrs to ret length */
                              &host_ad,         /* P4  adrs output */
                              0, 0);
           if (((status & 1) && (iosb[0] & 1)) == 0) {
              printf("Failed to get INET address for host %s \n",
                      host_name.dsc$a_pointer);
              return (status) ;
            }
    /*
    ** Return the host Internet address
    */
            addr = addr_buff[0];

    /*
    ** Deassign the INET dev channel
    */
            SYS$DASSGN (channel);

            return (status);
    }

# IO$_DEACCESS

> The IO$_DEACCESS function closes a connection. You can use a flag to specify whether pending I/O operations will be completed or discarded before the function is completed. After the function completes, $QIOs to transmit data are no longer allowed. To resume transmitting on the channel being used, you must issue the appropriate functions to initialize a communication link. If it is required for the protocol, you must also issue $QIOs with IO$_SETMODE, and if it is required for the protocol, IO$_ACCESS as well.

> Issuing an IO$_DEACCESS function disconnects the link between the two communicating agents previously established with an IO$_ACCESS function. The connection is discontinued, but messages queued for transmission are sent to the connection peer before finally disconnecting the link.

> Previous | Next | Contents