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 IBM® i 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 address from which the message was received

  • The vector array in which the data received is stored

  • The ancillary data(BSD 4.4/UNIX98); or an access rights list in which the descriptors received are stored.
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 from which the message was received. For further information about the structure of socket addresses, see the Socket programming topic collection. 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 and descriptors are not being passed, the msg_control field must be initialized to NULL and the msg_controllen field must be initialized to 0. The following tables list 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 ):

Ancillary Data Types That Apply to the IP Layer (where cmsg_level is IPPROTO_IP):

Ancillary Data Types That Apply to the IPv6 Layer (where cmsg_level is IPPROTO_IPV6):

Macros are provided for navigating these structures.

  • CMSG_DATA(cmsg) If the argument is a pointer to a cmsghdr structure, this macro returns an unsigned character pointer to the data array associated with the cmsghdr structure.
  • CMSG_NXTHDR(mhdr,cmsg) If the first argument is a pointer to a msghdr structure and the second argument is a pointer to a cmsghdr structure in the ancillary data, pointed to by the msg_control field of that msghdr structure, this macro returns a pointer to the next cmsghdr structure, or a null pointer if this structure is the last cmsghdr in the ancillary data.
  • CMSG_FIRSTHDR(mhdr) If the argument is a pointer to a msghdr structure, this macro returns a pointer to the first cmsghdr structure in the ancillary data associated with this msghdr structure, or a null pointer if there is no ancillary data associated with the msghdr structure.

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

  • MSG_TRUNC Message data was truncated
  • MSG_CTRUNC Ancillary data was truncated.
  • MSG_EOR End of record (if supported by the protocol).
  • MSG_OOB Out-of-band data.


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:

Authorities


Return Value

recvmsg() returns an integer. Possible values are:

Error Conditions

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



Error Messages



Usage Notes

  1. The following applies to sockets that use a connection-oriented transport service (for example, sockets with a type of SOCK_STREAM),
    • The msg_name and msg_namelen fields in the structure pointed to by the message_structure parameter are ignored.

    • A returned value of zero indicates one of the following:
      • The partner program has issued a close() for the socket.

      • The partner program has issued a shutdown() to disable writing to the socket.

      • The connection is broken and the error was returned on a previously issued socket function.

      • A shutdown() to disable reading was previously done on the socket.

  2. The following applies to sockets that use a connectionless transport service (for example, a socket with a type of SOCK_DGRAM):
    • If a connect() has been issued previously, then data can be received only from the address specified in the previous connect().

    • If the msg_name field is set to NULL or msg_namelen field specifies a value of zero, the address from which data is received is discarded.

    • If the length of the address to be returned exceeds the length specified by the msg_namelen field, the returned address is truncated.

    • If the socket is using an address family of AF_UNIX, the address (which is a path name) is returned in the default coded character set identifier (CCSID) currently in effect for the job.

    • If the socket is using an address family of AF_UNIX_CCSID, the output structure sockaddr_unc defines the format and coded character set identifier (CCSID) of the address (which is a path name).

    • The entire message must be read in a single read operation. If the size of the message is too large to fit in the user supplied buffer, the remaining bytes of the message are discarded.

    • A returned value of zero indicates one of the following:
      • The partner program has sent a NULL message (a datagram with no user data).

      • A shutdown() to disable reading was previously done on the socket.

      • The buffer length specified was zero.

  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:

    • The same user profile as the source job (in essence, passing the descriptor to yourself)
    • *ALLOBJ special authority

    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:
    • The function return value (the total number of bytes received).

    • The lengths of the buffers pointed to by iov_base.

  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 about text conversion.

  8. The following functions can be used to parse a routing header for IPV6_RTHDR:
  9. The following functions can be used to parse an options header for IPV6_HOPOPTS, IPV6_DSTOPTS, or IPV6_RTHDRDSTOPTS:

Related Information



API introduced: V3R1

[ Back to top | UNIX-Type APIs | APIs by category ]