recvmsg()--Receive a Message Over a Socket


  BSD 4.3 Syntax
  #include <sys/types.h>
  #include <sys/socket.h>

 int recvmsg(int socket_descriptor,
             struct msghdr *message_structure,
             int flags)

  Service Program Name: QSOSRV1

  Default Public Authority: *USE

  Threadsafe: Yes



  UNIX 98 Compatible Syntax
  #define _XOPEN_SOURCE 520
  #include <sys/socket.h>

 ssize_t recvmsg(int socket_descriptor,
                 struct msghdr *message_structure,
                 int flags)

  Service Program Name: QSOSRV1

  Default Public Authority: *USE

  Threadsafe: Yes

The recvmsg() function is used to receive data or descriptors or both through a connected or unconnected socket.

There are two versions of the API, as shown above. The base i5/OS API uses BSD 4.3 structures and syntax. The other uses syntax and structures compatible with the UNIX 98 programming interface specifications. You can select the UNIX 98 compatible interface with the _XOPEN_SOURCE macro.


Parameters

socket_descriptor
(Input) The socket descriptor that is to be read from.

message_structure
(I/O) The pointer to the message structure that contains the following: The structure pointed to by the message_structure parameter is defined in <sys/socket.h>.

The BSD 4.3 structure is:

      struct msghdr {
        caddr_t       msg_name;
        int           msg_namelen;
        struct iovec *msg_iov;
        int           msg_iovlen;
        caddr_t       msg_accrights;
        int           msg_accrightslen;
      };

The BSD 4.4/UNIX 98 compatible structure is:

      struct msghdr {
        void         *msg_name;
        socklen_t     msg_namelen;
        struct iovec *msg_iov;
        int           msg_iovlen;
        void         *msg_control;      /* Set to NULL if not needed  */
        socklen_t     msg_controllen;   /* Set to 0 if not needed     */
        int           msg_flags;
      };

The msg_name and msg_namelen fields contain the address and address length to which the message is sent. For further information on the structure of socket addresses, see Sockets Programming in the iSeries Information Center. If the msg_name field is set to a NULL pointer, the address information is not returned.

The msg_iov and msg_iovlen fields are for scatter/gather I/O.

The BSD 4.3 structure uses the msg_accrights and msg_accrightslen fields to pass descriptors. The msg_accrights field is a list of zero or more descriptors, and msg_accrightslen is the total length (in bytes) of the descriptor list.

The BSD 4.4/UNIX 98 compatible structure uses the msg_control and msg_controllen fields to pass ancillary data. The msg_control field is a pointer to ancillary data (of length msg_controllen) with the form:

     struct cmsghdr {
           socklen_t cmsg_len;    /* # bytes, including this header */
           int       cmsg_level;  /* originating protocol           */
           int       cmsg_type;   /* protocol-specific type         */
                         /* followed by unsigned char cmsg_data[];  */
     };

The cmsg_len field is the total length including this header. cmsg_level is the originating protocol. cmsg_type is the protocol-specific type. If ancillary data is not being passed, the msg_control field must be initalized to NULL and the msg_controllen field must be initialized to 0. The following table lists the supported ancillary data types when using the BSD 4.4/UNIX 98 compatible structures.

Ancillary Data Types That Apply to the Socket Layer (where cmsg_level is SOL_SOCKET ):

cmsg_type cmsg_data
SCM_RIGHTS The rest of the buffer is a list of zero or more descriptors received.

This ancillary data type is only supported for sockets with an address family of AF_UNIX or AF_UNIX_CCSID.

Macros are provided for navigating these structures.

The BSD 4.4/UNIX 98 compatible structure has the msg_flags for message level flags including:



flags
(Input) A flag value that controls the reception of the data. The flags value is either zero, or is obtained by performing an OR operation on one or more of the following constants:
MSG_OOB Receive out-of-band data. Valid only for sockets with an address family of AF_INET or AF_INET6 and type SOCK_STREAM.
MSG_PEEK Obtain a copy of the message without removing the message from the socket.
MSG_WAITALL Wait for a full request or an error.

Authorities


Return Value

recvmsg() returns an integer. Possible values are:

Error Conditions

When recvmsg() fails, errno can be set to one of the following:

[EACCES] Permission denied.

The socket pointed to by the socket_descriptor parameter is using a connection-oriented transport service, and a connect() was previously completed. The process, however, does not have the appropriate privileges to the objects that were needed to establish a connection. For example, the connect() required the use of an APPC device that the process was not authorized to.

If the msg_accrights and msg_accrightslen fields (or the BSD 4.4/UNIX 98 compatible fields msg_control and msg_controllen) were specified and descriptors were sent, this error indicates that this job does not have the appropriate privileges required to receive the descriptor. When this occurs, the descriptor is reclaimed by the system and the resource that it represented is closed.

[EBADF] Descriptor not valid.

[ECONNABORTED] Connection ended abnormally.

This error code indicates that the transport provider ended the connection abnormally because of one of the following:

  • The retransmission limit has been reached for data that was being sent on the socket.

  • A protocol error was detected.
[ECONNREFUSED] The destination socket refused an attempted connect operation.

[ECONNRESET] A connection with a remote socket was reset by that socket.

[EFAULT] Bad address.

The system detected an address which was not valid while attempting to access the message_structure parameter or a field within the structure pointed to by the message_structure parameter.

[EINTR] Interrupted function call.

[EINVAL] Parameter not valid.

This error code indicates one of the following:

  • The msg_iovlen field or the iov_len field in a iovec structure specifies a negative value.

  • The flags parameter specifies a value that includes the MSG_OOB flag, but no OOB data was available to be received.

  • The flags parameter specifies a value that includes the MSG_OOB flag, and the socket option SO_OOBINLINE has been set.

  • The socket_descriptor parameter points to a socket that is using a connectionless transport service, is not a socket of type SOCK_RAW, and is not bound to an address.

  • The msg_accrightslen field in the msghdr structure specifies a negative value or is not large enough when msg_accrights was specified.

  • The msg_controllen field in the msghdr structure specifies a negative value or is not large enough when msg_control was specified.
[EIO] Input/output error.

[EMFILE] Too many descriptions for this process.

[EMSGSIZE] Message size out of range.

The msg_iovlen field specifies a value that is greater than [MSG_MAXIOVLEN] (defined in <sys/socket.h>).

[ENOBUFS] There is not enough buffer space for the requested operation.

[ENOTCONN] Requested operation requires a connection.

This error code is returned only on sockets that use a connection-oriented transport service.

[ENOTSOCK] The specified descriptor does not reference a socket.

[EOPNOTSUPP] Operation not supported.

This error code indicates one of the following:

  • The flags parameter specifies a value that includes the MSG_OOB flag, but the socket_descriptor parameter points to a connectionless socket.

  • The flags parameter specifies a value that includes the MSG_OOB flag, but the socket_descriptor parameter points to a socket that does not have an address family of AF_INET or AF_INET6.
[ETIMEDOUT] A remote host did not respond within the timeout period.

A non-blocking connect() was previously issued that resulted in the connection establishment timing out. No connection is established. This error code is returned only on sockets that use a connection-oriented transport service.

[EUNATCH] The protocol required to support the specified address family is not available at this time.

[EUNKNOWN] Unknown system state.

[EWOULDBLOCK] Operation would have caused the thread to be suspended.


Error Messages

Message ID Error Message Text
CPE3418 E Possible APAR condition or hardware failure.
CPF9872 E Program or service program &1 in library &2 ended. Reason code &3.
CPFA081 E Unable to set return value or error code.


Usage Notes

  1. The following applies to sockets that use a connection-oriented transport service (for example, sockets with a type of SOCK_STREAM),
  2. The following applies to sockets that use a connectionless transport service (for example, a socket with a type of SOCK_DGRAM):
  3. The passing of descriptors is only supported over sockets that have an address family of AF_UNIX or AF_UNIX_CCSID. The msg_accrightslen and the msg_accrights fields (or the BSD 4.4/UNIX 98 compatible fields msg_control and msg_controllen) are ignored if the socket has any other address family. The value of msg_accrightslen (or the BSD 4.4/UNIX 98 compatible field msg_controllen) should be checked to determine if a descriptor has been returned. When you use sendmsg() and recvmsg() to pass descriptors, the target job must be running with either of the following:

    If the target job closes the receiving end of the UNIX domain socket while a descriptor is in transit, the descriptor is reclaimed by the system, and the resource that it represented is closed. For files and directories, the ability to pass descriptors using sendmsg() and recvmsg() is only supported for objects in the Root, QOpenSys, User-defined file systems (UDFS), and Network File System (NFS).

    Note: The recvmsg() API will not block unless a data buffer is specified.

  4. recvmsg() accepts a pointer to an array of iovec structures in the msghdr structure. The msg_iovlen field is used to determine the number of elements in the array (the number of iovec structures specified). When recvmsg() is issued, the system processes the array elements one at a time, starting with the first structure. For each element of the array (for each structure), iov_len bytes of received data are placed in storage pointed to by iov_base. Data is placed in storage until all buffers are full, or until there is no more data to receive. Only the memory pointed to by iov_base is updated. No change is made to the iov_len fields. To determine the end of the data, the application program must use the following:
  5. When you develop in C-based languages and an application is compiled with the _XOPEN_SOURCE macro defined to the value 520 or greater, the recvmsg() API is mapped to qso_recvmsg98().

  6. If this function is called by a thread executing one of the scan-related exit programs (or any of its created threads), it will fail with error code [ENOTSUP]. See Integrated File System Scan on Open Exit Programs and Integrated File System Scan on Close Exit Programs for more information.

  7. When the descriptor is obtained using recvmsg(), any information accessed using that descriptor with the various read and write interfaces will be in binary, even if the original descriptor's accesses would have had text conversions occur. See Using CCSIDs and code pages in the open--Open file documentation for more information on text conversion.


Related Information



API introduced: V3R1
Top | UNIX-Type APIs | APIs by category