Using _XOPEN_SOURCE for UNIX 98 Compatibility

There are two versions of most sockets APIs. The base IBM® i API uses BSD 4.3 structures and syntax. The other uses syntax and structures compatible with BSD 4.4 and the UNIX® 98 programming interface specifications. You can select the UNIX 98 compatible interface by defining the _XOPEN_SOURCE macro to a value of 520 or greater.

When you develop in C-based languages and an application is compiled with the _XOPEN_SOURCE macro defined to the value 520 or greater, some sockets APIs are mapped to internal names, as shown in the following table:

Mapped name Internal name
accept() qso_accept98()
accept_and_recv() qso_accept_and_recv98()
bind() qso_bind98()
bind2addrsel() qso_bind2addrsel98()
connect() qso_connect98()
endhostent() qso_endhostent98()
endnetent() qso_endnetent98()
endprotoent() qso_endprotoent98()
endservent() qso_endservent98()
getaddrinfo() qso_getaddrinfo98()
gethostbyaddr() qso_gethostbyaddr98()
gethostbyaddr_r() qso_gethostbyaddr_r98()
gethostname() qso_gethostname98()
gethostname_r() qso_gethostname_r98()
gethostbyname() qso_gethostbyname98()
gethostent() qso_gethostent98()
getnameinfo() qso_getnameinfo98()
getnetbyaddr() qso_getnetbyaddr98()
getnetbyname() qso_getnetbyname98()
getnetent() qso_getnetent98()
getpeername() qso_getpeername98()
getprotobyname() qso_getprotobyname98()
getprotobynumber() qso_getprotobynumber98()
getprotoent() qso_getprotoent98()
getsockname() qso_getsockname98()
getsockopt() qso_getsockopt98()
getservbyname() qso_getservbyname98()
getservbyport() qso_getservbyport98()
getservent() qso_getservent98()
getsourcefilter() qso_getsourcefilter98()
inet_addr() qso_inet_addr98()
inet6_is_srcaddr() qso_inet_is_srcaddr98()
inet_lnaof() qso_inet_lnaof98()
inet_makeaddr() qso_inet_makeaddr98()
inet_netof() qso_inet_netof98()
inet_network() qso_inet_network98()
listen() qso_listen98()
Rbind() qso_Rbind98()
recv() qso_recv98()
recvfrom98() qso_recvfrom98()
recvmsg() qso_recvmsg98()
send() qso_send98()
sendmsg() qso_sendmsg98()
sendto() qso_sendto98()
sethostent() qso_sethostent98()
setnetent() qso_setnetent98()
setprotoent() qso_setprotoent98()
setservent() qso_setprotoent98()
setsockopt() qso_setsockopt98()
setsourcefilter() qso_setsourcefilter98()
shutdown() qso_shutdown98()
socket() qso_socket98()
socketpair() qso_socketpair98()

Application not using C-based languages can use the internal names if necessary.

Using _XOPEN_SOURCE also changes some of the structures used by sockets to match BSD 4.4/UNIX 98 standards. The differences are summarized in the following table:

BSD 4.3 structure BSD 4.4/UNIX 98 compatible structure
 typedef int socklen_t;
 typedef unsigned short sa_family_t;

 struct sockaddr {
    u_short sa_family;
    char    sa_data[14];
 };


 struct sockaddr_un {

   short       sun_family;
   char        sun_path[126];
 };


struct sockaddr_in {

   short           sin_family;
   u_short         sin_port;
   struct in_addr  sin_addr;
   char            sin_zero[8];

};


struct sockaddr_in6 {
   sa_family_t     sin6_family;
   in_port_t       sin6_port;
   uint32_t        sin6_flowinfo;
   struct in6_addr sin6_addr;
   uint32_t        sin6_scope_id;
};
 typedef int socklen_t;
 typedef uchar sa_family_t;

 struct sockaddr {
    uint8_t     sa_len;
    sa_family_t sa_family;
    char        sa_data[14];
 };

 struct sockaddr_un {

   uint8_t     sun_len;
   sa_family_t sun_family;
   char        sun_path[126];
 };

struct sockaddr_in {

   uint8_t         sin_len;
   sa_family_t     sin_family;
   u_short         sin_port;
   struct in_addr  sin_addr;
   char            sin_zero[8];

};

struct sockaddr_in6 {
   uint8_t         sin6_len;    
   sa_family_t     sin6_family;
   in_port_t       sin6_port;
   uint32_t        sin6_flowinfo;
   struct in6_addr sin6_addr;
   uint32_t        sin6_scope_id;
};
 struct msghdr {
   caddr_t       msg_name;
   int           msg_namelen;
   struct iovec *msg_iov;
   int           msg_iovlen;
   caddr_t       msg_accrights;
   int           msg_accrightslen;
 };
 struct msghdr {
   void         *msg_name;
   socklen_t     msg_namelen;
   struct iovec *msg_iov;
   int           msg_iovlen;
   void         *msg_control;
   socklen_t     msg_controllen;
   int           msg_flags;
 };
 (no equivalent)
 struct cmsghdr {
         socklen_t cmsg_len;
         int       cmsg_level;
         int       cmsg_type;
 };
 #define _SS_MAXSIZE 304
 #define _SS_ALIGNSIZE (sizeof (char*))
 #define _SS_PAD1SIZE (_SS_ALIGNSIZE -
                        sizeof(sa_family_t))
 #define _SS_PAD2SIZE (_SS_MAXSIZE -
                        (sizeof(sa_family_t) +
                        _SS_PAD1SIZE +
                        _SS_ALIGNSIZE))

 struct sockaddr_storage {
     sa_family_t   ss_family;
     char         _ss_pad1[_SS_PAD1SIZE];
     char*        _ss_align;
     char         _ss_pad2[_SS_PAD2SIZE];
 };
 #define _SS_MAXSIZE 304
 #define _SS_ALIGNSIZE (sizeof (char*))
 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - (sizeof(uint8_t) +
                        sizeof(sa_family_t)))
 #define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(uint8_t) +
                        sizeof(sa_family_t) +
                        _SS_PAD1SIZE + _SS_ALIGNSIZE))

 struct sockaddr_storage {
     uint8_t       ss_len;

     sa_family_t   ss_family;
     char         _ss_pad1[_SS_PAD1SIZE];
     char*        _ss_align;
     char         _ss_pad2[_SS_PAD2SIZE];
 };
 (no equivalent)
 typedef int in_addr_t;
 typedef unsigned short in_port_t;

Usage Notes

  1. The struct sockaddr length field (sa_len and the address family specific equivalents: sun_len, sin_len, and sin6_len) is only provided for BSD 4.4 compatibility. It is not necessary to use this field even when using BSD 4.4/UNIX 98 compatibility. The field is ignored on input addresses (like the local_address parameter on bind()) and will be properly set on output addresses (like the address parameter on accept()).

  2. The AF_UNIX_CCSID address sockaddr_unc has not been updated with a length field equivalent to sa_len. If you use sa_len to set a length on this address, it will be ignored on input addresses and set to zero on output addresses.

  3. The structure sockaddr_storage is used to declare storage for any address family address. This structure is large enough and aligned for any protocol-specific structure. It may then be cast as sockaddr structure for use on the APIs. The ss_family field of the sockaddr_storage will always align with the family field of any protocol-specific structure.

    Note: The storage allocated is larger than 255 bytes so it's size should not be used for sa_len. The actual protocol-specific structure size should be used instead.

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