sendmsg()--Send a Message Over a Socket


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

 int sendmsg(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 sendmsg(int socket_descriptor,
                 const struct msghdr *message_structure,
                 int flags)

  Service Program Name: QSOSRV1

  Default Public Authority: *USE

  Threadsafe: Yes

The sendmsg() function is used to send data or descriptors or ancillary data or a combination of these 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 written to.

message_structure
(I/O) The pointer to the message structure that contains the following:
  • The address to which the message is to be sent

  • The vector array in which the data to be sent is stored

  • The ancillary data(BSD 4.4/UNIX98); or an access rights list in which the descriptors to be sent 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 to which the message is sent. For further information about the structure of socket addresses, see the Sockets 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 msg_flags field is ignored for sendmsg().

flags
(Input) A flag value that controls the transmission 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

When the address family of the socket identified by the socket_descriptor is AF_INET and is running IP over SNA, the thread must have retrieve, insert, delete, and update authority to the APPC device. When the thread does not have this level of authority, an errno of EACCES is returned.

The user profile for the thread must have *IOSYSCFG special authority to send ancillary data when:

Return Value

sendmsg() returns an integer. Possible values are:


Error Conditions

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



Error Messages



Usage Notes

  1. 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. 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 Root, QOpenSys, User-defined file systems (UDFS), and Network File System (NFS).

  2. sendmsg() is an atomic operation in that it produces one packet of data each time the call is issued on a connectionless socket. For example, a sendmsg() to a datagram socket will result in a single datagram.

  3. A destination address cannot be specified if the socket pointed to by the socket_descriptor parameter already has a destination address associated with it. To not specify an address, users must set the msg_name field to NULL or set the msg_namelen field to zero. (Not specifying an address by setting the msg_namelen field to zero is an IBM® extension.)

    Note: The msg_name and msg_namelen fields are ignored if the socket is using a connection-oriented transport service.

  4. If the socket is using a connectionless transport device, the socket is not bound to an address, and the socket type is SOCK_DGRAM, the system automatically selects an address (INADDR_ANY or in6addr_any and an available port number) and binds it to the socket before sending the data. The IPV6_ADDR_PREFERECES socket option flags set on setsockopt() will be taken into consideration when selecting the source address on which to send the outgoing data.

  5. To broadcast on an AF_INET socket, the socket option SO_BROADCAST must be set (with a setsockopt()).

  6. When using a connection-oriented transport service, all errors except [EUNATCH] and [EUNKNOWN] are mapped to [EPIPE] on an output operation when either of the following occurs:
    • A connection that is in progress is unsuccessful.

    • An established connection is broken.
    To get the actual error, use getsockopt() with the SO_ERROR option, or perform an input operation (for example, read()).

  7. If the socket is using an address family of AF_UNIX, the destination address (which is a path name) is assumed to be in the default coded character set identifier (CCSID) currently in effect for the job. For AF_UNIX_CCSID, the destination address is assumed to be in the format and coded character set identifier (CCSID) specified in the sockaddr_unc.

  8. For AF_INET sockets over SNA, type SOCK_DGRAM, if a datagram can not be delivered, no errors are returned. (As an example, a datagram might not be delivered if there is no datagram application at the remote host listening at the requested port.)

  9. 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 sendmsg() API is mapped to qso_sendmsg98().

  10. The following functions can be used to build a routing header for IPV6_RTHDR:

  11. The following functions can be used to build an options header for IPV6_HOPOPTS, IPV6_DSTOPTS, or IPV6_RTHDRDSTOPTS:

  12. Data options set using ancillary data on sendmsg() are known as non-sticky options. Non-sticky options apply for only a single datagram. Ancillary data only applies to sockets of type SOCK_DGRAM and SOCK_RAW. For the datagram being sent, non-sticky options will override any sticky options that have been set on the socket using setsockopt().

Related Information



API introduced: V3R1

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