An IO$_DEACCESS function prevents the user process that issued the function from sending any more data. It also ensures successful delivery of all data queued before the IO$_DEACCESS function was issued, unless there is a fatal error. A fatal error will be signaled. The user may continue to receive data until it is signaled that the connection peer has closed the connection.
Before a receiving process with a connection-oriented protocol is notified about a synchronous disconnection, all the data that the peer sent is received.
You can specify a wait time or time-to-linger socket parameter (UCX$C_LINGER option) for transmission completion before disconnecting the connection. Use the IO$_SETMODE or IO$_SETCHAR function to set and clear the UCX$C_LINGER option.
If you set the UCX$C_LINGER option, a $QIO call that uses the IO$_DEACCESS function allows data queued to the socket to arrive at the destination. The system is blocked until data arrives at the remote socket. The socket data structure remains open for the duration of the TCP idle time interval.
If you do not set the UCX$C_LINGER option (option is set to 0), a $QIO call that uses the IO$_DEACCESS function discards any data queued to the socket and deallocates the socket data structure.
Note
For compatibility with UNIX TCP/IP, the UCX implementation of TCP/IP forces a time-to-linger of 2 minutes on stream sockets.
The equivalent C Socket function is close() or shutdown().
p4
UCX usage flags type byte (unsigned) access read only mechanism by value
This argument is used only with the IO$M_SHUTDOWN function modifier. The following table lists the IO$M_SHUTDOWN flags (defined in the UCX$INETDEF symbol definition file) that you can use to specify the disposition of pending I/O operations.
Shutdown Flag Description UCX$C_DSC_RCV Discards messages from the receive queue and disallows further receiving. Pending messages in the receive queue for this connection are discarded. The socket is put in CANTRCVMORE state. UCX$C_DSC_SND Discards messages from the send queue and disallows further sending. Pending messages in the transmit queue for this connection are discarded. The socket is put in CANTSNDMORE state. UCX$C_DSC_ALL Discards all messages and disallows both sending and receiving (socket is put in the CANTRCVMORE and CANTSNDMORE states). All pending messages are discarded. Specifying this flag has the same effect as issuing a $CANCEL function followed by an IO$_DEACCESS function without any flags.
IO$M_SHUTDOWN Causes all or part of the full-duplex connection on the device socket to be shut down. The p4 parameter specifies shutdown flags. 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 error code SS$_SUSPENDED.
SS$_ABORT Programming error, INET management error, or hardware error. The execution of the I/O function aborts. A disconnect was requested on a connection that already started a disconnect operation. SS$_BADPARAM Programming error. You specified a $QIO function using an invalid parameter. You tried to execute one of the I/O functions without specifying a device socket. Instead, you should first create a device socket by issuing a $QIO with the IO$_SETMODE function and the proper parameters. SS$_CANCEL Warning code. The I/O operation canceled by executing a $CANCEL system service routine. SS$_DEVINACT INET management error. The driver was not started. You must execute a UCX START COMMUNICATION before issuing a $QIO operation. SS$_DEVNOTMOUNT INET management error. You improperly executed the INET startup procedure. The driver was loaded, but the INET_ACP function was not activated. SS$_NOLINKS Programming error because of one of the following reasons:
- The socket was not connected (TCP/IP) or an INET port and address were not specified with an IO$_ACCESS (UDP/IP) or IP.
- You tried to disconnect an unconnected socket.
SS$_SHUT The network is being shut down.
Read functions transfer data received from an internet host and store that data in system-dynamic space on the virtual memory address of the user process. The TCP/IP software provides the READ I/O function code IO$_READVBLK, which reads a virtual block of a stream socket, datagram, or raw socket.Received messages are stored in system-dynamic memory and copied to user buffers when the software issues a read operation.
If you specify multiple buffers, the buffers are filled in the order specified in the p6 list.
The TCP/IP software fills in these user buffers according to the protocol (socket type).
For TCP/IP (stream socket), data is buffered in system space as a stream of bytes. The user buffer specified with a $QIO is filled in with data that is being buffered in system space. The I/O is completed when there is no more data in the system space, or there is no more available space in the user buffer. Data that is buffered in the system space but did not fit in the user buffer is available to the user in subsequent $QIOs. No data is discarded or lost.
Datagram and raw socket data is buffered in system space as a chain of records. The user buffer specified with a $QIO is filled in with data that is being buffered in one record in system space. One I/O operation reads data from one record. The I/O completes when there is no more space in the user buffer or when all data from the record has been transferred to the user buffer. Data remaining in the current record in system space that did not fit in the user buffer is discarded. A subsequent $QIO reads data from the next record buffered in system space.
Use the UCX SHOW DEVICE_SOCKET /FULL command to display counters related to read operations.
The equivalent C Socket function is the recv*() or read() routine.
Three programming examples for the IO$_READVBLK routine follow this command description. Example 4-9 uses the MACRO-32 programming language to read a vectored buffer. Example 4-10 uses the C programming language to read a vectored buffer. Example 4-11 uses the C programming language to read from an INET driver.
p1
UCX usage buffer type longword (unsigned) access read only mechanism by reference
The p1 argument specifies the starting virtual address of the buffer that is to receive the data.p2
UCX usage buffer length type longword (unsigned) access read only mechanism by value
The p2 argument specifies the size (in bytes) of the buffer that is to receive the data.p3
UCX usage remote socket name for the source of the message type longword (unsigned) access read only mechanism by descriptor
The p3 argument specifies the address of a UCX item_list_3 descriptor with a buffer that contains the remote socket name of the source of the message. The remote socket is composed of the remote port and host internet address.The parameter name for the descriptor is UCX$C_SOCK_NAME, which is defined in the UCX$INETDEF symbol definition file.
p4
UCX usage flags type word (unsigned) access read only mechanism by value
The p4 argument specifies the flags for the read operation. The valid flags are described in Table 4-8.
Table 4-8 Valid Flags for the p4 Argument Flag Description UCX$C_MSG_OOB Reads an out-of-band byte. UCX$C_MSG_PEEK Reads a message but leaves the message in the queue. Another read operation shows the same message. UCX$C_MSG_NBIO Does not block the I/O operation if the receive queue is empty. Similar to using IO$M_NOWAIT. UCX$C_MSG_PURGE Flushes data from the queue. Similar to using IO$M_PURGE. UCX$C_MSG_BLOCKALL Blocks the completion of the operation until the buffer is filled completely or until the connection is closed. Similar to using IO$M_LOCKBUF. p6
UCX usage UCX item_list_2 type longword (unsigned) access read only mechanism by descriptor
The p6 argument specifies the address for the descriptor of an output parameter list.The maximum number of buffers you can specify with the p6 argument is 16.
If you use the p1 and p2 arguments, do not use the p6 argument; they are mutually exclusive. You either use p1 and p2, or you use p6 instead. The software first checks to see if the p1 argument is used. If p1 is not used, the software checks to see if the p6 argument is being used. If neither the p1 nor the p6 arguments are used, the software returns an error code.
The transfer-length value returned in the I/O status block is the total number of bytes transferred to the buffer or multiple buffers.
IO$M_INTERRUPT Reads an out-of-band (OOB) message. This has the same effect as specifying the UCX$C_MSG_OOB flag. On receiving a TCP/IP OOB character, TCP/IP stores the pointer in the received stream with the character that precedes the OOB character. A read operation with a user-buffer size larger than the size of the received stream up to the OOB character completes and returns to the user the received stream up to, but not including, the OOB character. To determine whether the socket must issue more read $QIOs before getting all the characters from the stream preceding an OOB character, poll the socket. To do this, issue a $QIO with the $IO_SENSEMODE function, and the UCX$C_IOCTL subfunction that specifies the SIOCATMARK command. The SIOCATMARK values are as follows:
- 0 = Issue more read QIOs to read more data before reading the OOB.
- 1 = The next read QIO will return the OOB.
Polling a socket is particularly useful when the OOBINLINE socket option is set. When the OOBINLINE is set, TCP/IP reads the OOB character with the characters in the stream (IO$_READVBLK), but not before reading the preceding characters. Use this polling mechanism to determine whether the first character in the user buffer on the next read is an OOB character. On a socket with the OOBINLINE option set to clear, a received OOB will always be read by issuing a $QIO with either the IO$_READVBLK!IO$M_INTERRUPT or IO$_READVBLK and the UCX$C_MSG_OOB flag set. This can occur, regardless of how many preceding characters in the stream have been returned to the user. IO$M_LOCKBUF Blocks the completion of the I/O operation until the user buffer is completely filled or until the connection is closed. This is particularly useful when you want to minimize the number of $QIO commands issued to read a data stream of a particular size. This function code is supported only for stream protocols. IO$M_NOWAIT 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 error code SS$_SUSPENDED. IO$M_PURGE Flushes data from the device socket receive queue (discards data). If the user buffer is larger than the amount of data in the queue, all data in the queue is flushed. This function works in the same manner for both datagram and stream sockets.
SS$_ABORT Programming error, INET management error, or hardware error. The execution of the I/O was aborted. SS$_ACCVIO Programming error. You tried to access an invalid memory location or buffer. SS$_BADPARAM Programming error. You used one of the following methods to specify a $QIO function with an invalid parameter:
- You executed an I/O function without specifying a device socket. You must first issue a $QIO with the IO$_SETMODE function and the proper parameters to create the device socket.
- You issued an IO$_READVBLK or IO$_WRITEVBLK function that does not specify a correct buffer address ( p1, p5 or p6 are null).
- You issued an IO$_READVBLK or IO$_WRITEVBLK function that specifies an invalid vectored buffer ( p5 or p6 are invalid address descriptors).
- The socket has the OOBINLINE option set, or there is no OOB character in the socket's OOB queue because the character was either already read or never received. This condition happens only if you use the IO$M_INTERRUPT modifier or set the UCX$C_MSG_OOB flag with IO$_READVBLK.
SS$_CANCEL Warning code. The I/O operation canceled by executing a $CANCEL system service routine. SS$_CONNECFAIL Programming error, INET management error, or hardware error. The connection was abnormally terminated. SS$_DEVINACT INET management error. The driver has not been started. You must execute a UCX START COMMUNICATION command before issuing a $QIO routine. SS$_DEVNOTMOUNT INET management error. You improperly executed the INET startup procedure. The driver was loaded, but the INET_ACP was not activated. SS$_INSFMEM INET management or programming error. There is not enough buffer space for allocation. The INET software needs more buffer space. You should set a higher quota for the dynamic buffer space, or shut down and restart your internet with a larger static buffer space. SS$_IVBUFLEN Programming error occurred for one of the following reasons:
- The size of the buffer for an I/O function is insufficient.
- You tried to issue an IO$_READVBLK or IO$_WRITEVBLK that specifies a correct buffer address ( p1 valid), but does not specify a buffer length ( p2 is null).
SS$_LINKDISCON A virtual circuit (TCP/IP) was closed at the initiative of the peer. SS$_NOLINKS Programming error. Read attempt on unconnected TCP socket. SS$_SHUT The network is being shut down. SS$_SUSPENDED The operation is blocked for one of the following reasons:
- No messages were received so the receive operation cannot complete. The socket is marked as nonblocking.
- The socket has the OOBINLINE option clear, and the OOB character has already been read.
SS$_TIMEOUT This applies to a socket that has KEEPALIVE set. The connection was idle for longer than the timeout interval (10 minutes is the default). SS$_UNREACHABLE Communication status. The remote host or network is unreachable.
Example 4-9 IO$_READVBLK Function (MACRO-32 Programming)
.title Read_v ;+ ; Read using a vectored buffer descriptor ;- .ident /01/ $inetsymdef ; INET symbols dev: .ascid /ucx$device:/ ; INET device name channel: .word 0 ; INET channel iostatus: .quad 0 ; I/O status block Ret_adr: .blkb 16 ; Buffer for remote host IP address Ret_len=.-Ret_adr leng: .long 0 ; Return length of Remote IP address loc_adr:.word INET$C_AF_INET ; INET family .word 5001 ; Port number ; Local host IP address .byte 128,20,20 ; Network/subnetwork number .byte 10 ; Host number .blkb 8 par11: .word INET$C_UDP ; UDP/IP protocol .word INET_PROTYP$C_DGRAM ; Datagram type of socket ; ; Item_list_3 descriptor for the Remote IP address ; par12: .long ret_len ; Length .address ret_adr ; Buffer address .address leng ; Returned length ; ; Item_list_2 descriptor for the Local IP address ; par13: .long ret_len ; Length .address loc_adr ; Address ; ; I/O Buffer ; buffer_1: .blkb 512 buflen=.-buffer_1 buffer_2: .blkb 512 buffer_3: .blkb 512 buffer_4: .blkb 512 buf_d: .long len_d .address buffer_d buffer_d: .long buflen .address buffer_1 .long buflen .address buffer_2 .long buflen .address buffer_3 .long buflen .address buffer_4 len_d=.-buffer_d .entry start,^m<> ; ; Assign an INET device ; $assign_s devnam=dev, chan=channel blbs r0,read brw exit ; ; Create and bind the device socket to the local host ; read: $qioW_s efn=#31,- ; Event flag chan=channel, - ; Channel func=#io$_setmode,- ; I/O Function iosb= iostatus, - ; I/O status block p1=par11,- ; Socket creation parameters P3=#Par13 ; Socket Bind parameters blbc r0,exit ; ; Perform a QIOW read operation ; $qiow_s efn=#31,- ; Event flag chan=channel, - ; Channel func=#io$_readvblk,- ; I/O function iosb= iostatus,- ; I/O status p3=#par12,-; Descriptor of the remote Host IP address P6=#buf_d ; Vectored buffer descriptor exit: ret ; Exit .end start
Example 4-10 IO$_READVBLK Function --- Vectored Buffers (C Programming)
#module read_vecio /* **++ ** ** This example does vectored buffers read ** **-- */ /* ** INCLUDE FILES */ #include <descrip.h> #include <ucx$inetdef.h> /* INET symbol definitions */ #include <iodef.h> /* ** */ struct bvec /* Structure definition for vec buf */ { int length ; char *b_adrs ; } ; struct sockaddr { /* Structure definition for socket adrs */ short inet_family ; short inet_port ; char adrs[4] ; char blkb[8] ; } ; main() { int status ; /* For return status */ short channel ; /* INET channel */ short sck_parm[2] ; /* Socket creation parameter */ char buf_1[12],buf_2[12],buf_3[12],buf_4[12] ; struct sockaddr remote_host ; /Socket adrs definition for rhst */ struct sockaddr local_host ; /Socket adrs definition for lhst */ struct itlst lhst_adrs ; struct itlst rhst_adrs ; struct bvec buf_vec[5] = { {12, &buf_1 }, {12, &buf_2 }, {12, &buf_3 }, {12, &buf_4 }, {0, 0 } } ; /* Descriptor for Inet device name */ struct dsc$descriptor dev = { 11, DSC$K_CLASS_S, DSC$K_DTYPE_T, "UCX$DEVICE:"} ; /* Descriptor for vectored buffer */ struct desc$descriptor buf_d = { 0, DSC$K_CLASS_S, DSC$K_DTYPE_T, 0} ; /* Initialize the parameters */ sck_parm[0] = INET$C_UDP ; /* UDP/IP protocol */ sck_parm[1] = INET_PROTYP$C_DGRAM ; /*Datagram type of socket*/ /* Itlst for local IP address */ lhst_adrs.lgth = sizeof(local_host); lhst_adrs.hst = &local_host ; rhst_adrs.lgth = sizeof(remote_host) ; rhst_adrs.hst = &remote_host ; buf_d.dsc$a_pointer = buf_vec; buf_d.dsc$w_length = sizeof(bvec) ; /* Initialize socket address for remote host */ remote_host.inet_family = INET$C_AF_INET ; /* INET family */ remote_host.inet_port = 5002 ; /* Port number */ remote_host.adrs[0] = 128 ; /* Network/subnetwork*/ remote_host.adrs[0] = 20 ; /* number */ remote_host.adrs[0] = 20 ; remote_host.adrs[0] = 156 ; /* Host number */ remote_host.blkb[0] = 0 ; remote_host.blkb[1] = 0 ; remote_host.blkb[2] = 0 ; remote_host.blkb[3] = 0 ; remote_host.blkb[4] = 0 ; remote_host.blkb[5] = 0 ; remote_host.blkb[6] = 0 ; remote_host.blkb[7] = 0 ; /* Initialize socket address for local host */ local_host.inet_family = AF_INET ; /* INET family */ local_host.inet_port = 5002 ; /* Port number */ local_host.adrs[0] = 128 ; /* Network/subnetwork*/ local_host.adrs[0] = 20 ; /* number */ local_host.adrs[0] = 20 ; local_host.adrs[0] = 156 ; /* Host number */ local_host.blkb[0] = 0 ; local_host.blkb[1] = 0 ; local_host.blkb[2] = 0 ; local_host.blkb[3] = 0 ; local_host.blkb[4] = 0 ; local_host.blkb[5] = 0 ; local_host.blkb[6] = 0 ; local_host.blkb[7] = 0 ; /* ** Assign a channel to INET device */ status = SYS$ASSIGN( &dev, &channel, 0, 0) ; if ((status & 1) == 0) { printf("Failed to assign channel to INET device \n") ; return(status) ; } /* ** Create and bind the device socket to local host */ status = SYS$QIOW( 31, /* Event flag */ channel, /* Channel number */ IO$_SETMODE, /* I/O function */ iosb, /* I/O status block */ 0, 0, &sck_parm, /* P1 Socket creation parameter */ 0, &lhst_adrs, /* P3 Socket bind parameter */ 0,0,0) ; if ((status & 1) == 0) { printf("Failed to create and bind the devicesocket \n") ; return(status) ; /* ** Perform the QIO read operation */ status = SYS$QIOW( 31, /* Event flag */ channel, /* Channel number */ IO$_READVBLK,/* I/O function */ iosb, /* I/O status block */ 0, 0, 0, 0, &rhst_adrs, /* P3 Remote host adrs desc */ 0, 0, &buf_d) ; /* P6 Vectored buffer desc */ if ((status & 1) == 0) { printf("Failed to read from device \n") ; return(status) ; } /* ** Deassign the INET dev channel */ SYS$DASSGN (channel); return(status) ; }
Example 4-11 IO$_READVBLK Function --- INET device (C Programming)
#module read_io /* **++ ** ** This example does read from INET device ** **-- */ /* ** INCLUDE FILES */ #include <descrip.h> #include <ucx$inetdef.h> /* INET symbol definitions */ #include <iodef.h> struct sockaddr { /* Structure definition for socket adrs */ short inet_family ; short inet_port ; char adrs[4] ; char blkb[8] ; } ; struct itlst { int lgth ; struct sockaddr *hst ; } ; main() { int status ; /* For return status */ short channel /* INET channel */ short sck_parm[2] ; /* Socket creation parameter */ int iosb [2] ; /* I/O status block */ struct sockaddr local_host ; /* Socket adrs definition for lhst */ struct itlst lhst_adrs ; char buf[128] ; int buflen = 128 ; /* Descriptor for Inet device name */ struct dsc$descriptor dev = { 3, DSC$K_CLASS_S, DSC$K_DTYPE_T, "UCX$DEVICE:"} ; /* Initialize the parameters */ sck_parm[0] = INET$C_UDP ; /* UDP/IP protocol */ sck_parm[1] = INET_PROTYP$C_DGRAM ; /* Datagram type of socket */ /* Itlst for local IP address */ lhst_adrs.lgth = sizeof(local_host); lhst_adrs.hst = &local_host ; /* ** Assign a channel to INET device */ status = SYS$ASSIGN( &dev, &channel, 0, 0) ; if ((status & 1) == 0) { printf("Failed to assign channel to INET device \n") ; return(status) ; } /* Initialize socket address for local host */ local_host.inet_family = INET$C_AF_INET ;/* INET family */ local_host.inet_port = 0 ; /* Port number */ local_host.adrs[0] = 128 ; /* Network/subnetwork*/ local_host.adrs[1] = 45 ; /* number */ local_host.adrs[2] = 45 ; local_host.adrs[3] = 216 ; /* Host number */ local_host.blkb[0] = 0 ; local_host.blkb[1] = 0 ; local_host.blkb[2] = 0 ; local_host.blkb[3] = 0 ; local_host.blkb[4] = 0 ; local_host.blkb[5] = 0 ; local_host.blkb[6] = 0 ; local_host.blkb[7] = 0 ; /* ** Create and bind the device socket to local host */ status = SYS$QIOW( 31, /* Event flag */ channel, /* Channel number */ IO$_SETMODE, /* I/O function */ iosb, /* I/O status block */ 0, 0, &sck_parm, /* P1 Socket creation parameter */ 0, &lhst_adrs, /* P3 Socket bind parameter */ 0,0,0) ; if ((status & 1) == 0) { printf("Failed to create and bind the device socket \n") ; return(status) ; } /* ** Perform the QIO read operation */ status = SYS$QIOW( 0, /* Event flag */ channel, /* Channel number */ IO$_READVBLK,/* I/O function */ iosb, /* I/O status block */ 0, 0, buf, /* P1 buffer */ buflen, /* P2 buffer length */ 0,0,0,0 ) ; if ((status & 1) == 0) { printf("Failed to read from inet device \n") ; return(status) ; } /* ** Deassign the INET dev channel */ SYS$DASSGN (channel); return(status) ; }
The Sense Mode (IO$_SENSEMODE) and Sense Characteristics (IO$_SENSECHAR) I/O functions return the characteristics of the internet pseudodevice.