summaryrefslogtreecommitdiffstats
path: root/man3/getaddrinfo.3
diff options
context:
space:
mode:
Diffstat (limited to 'man3/getaddrinfo.3')
-rw-r--r--man3/getaddrinfo.3853
1 files changed, 853 insertions, 0 deletions
diff --git a/man3/getaddrinfo.3 b/man3/getaddrinfo.3
new file mode 100644
index 0000000..1bbbb23
--- /dev/null
+++ b/man3/getaddrinfo.3
@@ -0,0 +1,853 @@
+'\" t
+.\" Copyright (c) 2007, 2008 Michael Kerrisk <mtk.manpages@gmail.com>
+.\" and Copyright (c) 2006 Ulrich Drepper <drepper@redhat.com>
+.\" A few pieces of an earlier version remain:
+.\" Copyright 2000, Sam Varshavchik <mrsam@courier-mta.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.\" References: RFC 2553
+.\"
+.\" 2005-08-09, mtk, added AI_ALL, AI_ADDRCONFIG, AI_V4MAPPED,
+.\" and AI_NUMERICSERV.
+.\" 2006-11-25, Ulrich Drepper <drepper@redhat.com>
+.\" Add text describing Internationalized Domain Name extensions.
+.\" 2007-06-08, mtk: added example programs
+.\" 2008-02-26, mtk; clarify discussion of NULL 'hints' argument; other
+.\" minor rewrites.
+.\" 2008-06-18, mtk: many parts rewritten
+.\" 2008-12-04, Petr Baudis <pasky@suse.cz>
+.\" Describe results ordering and reference /etc/gai.conf.
+.\"
+.\" FIXME . glibc's 2.9 NEWS file documents DCCP and UDP-lite support
+.\" and is SCTP support now also there?
+.\"
+.TH getaddrinfo 3 2023-07-20 "Linux man-pages 6.05.01"
+.SH NAME
+getaddrinfo, freeaddrinfo, gai_strerror \- network address and
+service translation
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netdb.h>
+.PP
+.BI "int getaddrinfo(const char *restrict " node ,
+.BI " const char *restrict " service ,
+.BI " const struct addrinfo *restrict " hints ,
+.BI " struct addrinfo **restrict " res );
+.PP
+.BI "void freeaddrinfo(struct addrinfo *" res );
+.PP
+.BI "const char *gai_strerror(int " errcode );
+.fi
+.PP
+.RS -4
+Feature Test Macro Requirements for glibc (see
+.BR feature_test_macros (7)):
+.RE
+.PP
+.BR getaddrinfo (),
+.BR freeaddrinfo (),
+.BR gai_strerror ():
+.nf
+ Since glibc 2.22:
+ _POSIX_C_SOURCE >= 200112L
+ glibc 2.21 and earlier:
+ _POSIX_C_SOURCE
+.fi
+.SH DESCRIPTION
+Given
+.I node
+and
+.IR service ,
+which identify an Internet host and a service,
+.BR getaddrinfo ()
+returns one or more
+.I addrinfo
+structures, each of which contains an Internet address
+that can be specified in a call to
+.BR bind (2)
+or
+.BR connect (2).
+The
+.BR getaddrinfo ()
+function combines the functionality provided by the
+.\" .BR getipnodebyname (3),
+.\" .BR getipnodebyaddr (3),
+.BR gethostbyname (3)
+and
+.BR getservbyname (3)
+functions into a single interface, but unlike the latter functions,
+.BR getaddrinfo ()
+is reentrant and allows programs to eliminate IPv4-versus-IPv6 dependencies.
+.PP
+The
+.I addrinfo
+structure used by
+.BR getaddrinfo ()
+contains the following fields:
+.PP
+.in +4n
+.EX
+struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ socklen_t ai_addrlen;
+ struct sockaddr *ai_addr;
+ char *ai_canonname;
+ struct addrinfo *ai_next;
+};
+.EE
+.in
+.PP
+The
+.I hints
+argument points to an
+.I addrinfo
+structure that specifies criteria for selecting the socket address
+structures returned in the list pointed to by
+.IR res .
+If
+.I hints
+is not NULL it points to an
+.I addrinfo
+structure whose
+.IR ai_family ,
+.IR ai_socktype ,
+and
+.I ai_protocol
+specify criteria that limit the set of socket addresses returned by
+.BR getaddrinfo (),
+as follows:
+.TP
+.I ai_family
+This field specifies the desired address family for the returned addresses.
+Valid values for this field include
+.B AF_INET
+and
+.BR AF_INET6 .
+The value
+.B AF_UNSPEC
+indicates that
+.BR getaddrinfo ()
+should return socket addresses for any address family
+(either IPv4 or IPv6, for example) that can be used with
+.I node
+and
+.IR service .
+.TP
+.I ai_socktype
+This field specifies the preferred socket type, for example
+.B SOCK_STREAM
+or
+.BR SOCK_DGRAM .
+Specifying 0 in this field indicates that socket addresses of any type
+can be returned by
+.BR getaddrinfo ().
+.TP
+.I ai_protocol
+This field specifies the protocol for the returned socket addresses.
+Specifying 0 in this field indicates that socket addresses with
+any protocol can be returned by
+.BR getaddrinfo ().
+.TP
+.I ai_flags
+This field specifies additional options, described below.
+Multiple flags are specified by bitwise OR-ing them together.
+.PP
+All the other fields in the structure pointed to by
+.I hints
+must contain either 0 or a null pointer, as appropriate.
+.PP
+Specifying
+.I hints
+as NULL is equivalent to setting
+.I ai_socktype
+and
+.I ai_protocol
+to 0;
+.I ai_family
+to
+.BR AF_UNSPEC ;
+and
+.I ai_flags
+to
+.BR "(AI_V4MAPPED\ |\ AI_ADDRCONFIG)" .
+(POSIX specifies different defaults for
+.IR ai_flags ;
+see NOTES.)
+.I node
+specifies either a numerical network address
+(for IPv4, numbers-and-dots notation as supported by
+.BR inet_aton (3);
+for IPv6, hexadecimal string format as supported by
+.BR inet_pton (3)),
+or a network hostname, whose network addresses are looked up and resolved.
+If
+.I hints.ai_flags
+contains the
+.B AI_NUMERICHOST
+flag, then
+.I node
+must be a numerical network address.
+The
+.B AI_NUMERICHOST
+flag suppresses any potentially lengthy network host address lookups.
+.PP
+If the
+.B AI_PASSIVE
+flag is specified in
+.IR hints.ai_flags ,
+and
+.I node
+is NULL,
+then the returned socket addresses will be suitable for
+.BR bind (2)ing
+a socket that will
+.BR accept (2)
+connections.
+The returned socket address will contain the "wildcard address"
+.RB ( INADDR_ANY
+for IPv4 addresses,
+.B IN6ADDR_ANY_INIT
+for IPv6 address).
+The wildcard address is used by applications (typically servers)
+that intend to accept connections on any of the host's network addresses.
+If
+.I node
+is not NULL, then the
+.B AI_PASSIVE
+flag is ignored.
+.PP
+If the
+.B AI_PASSIVE
+flag is not set in
+.IR hints.ai_flags ,
+then the returned socket addresses will be suitable for use with
+.BR connect (2),
+.BR sendto (2),
+or
+.BR sendmsg (2).
+If
+.I node
+is NULL,
+then the network address will be set to the loopback interface address
+.RB ( INADDR_LOOPBACK
+for IPv4 addresses,
+.B IN6ADDR_LOOPBACK_INIT
+for IPv6 address);
+this is used by applications that intend to communicate
+with peers running on the same host.
+.PP
+.I service
+sets the port in each returned address structure.
+If this argument is a service name (see
+.BR services (5)),
+it is translated to the corresponding port number.
+This argument can also be specified as a decimal number,
+which is simply converted to binary.
+If
+.I service
+is NULL, then the port number of the returned socket addresses
+will be left uninitialized.
+If
+.B AI_NUMERICSERV
+is specified in
+.I hints.ai_flags
+and
+.I service
+is not NULL, then
+.I service
+must point to a string containing a numeric port number.
+This flag is used to inhibit the invocation of a name resolution service
+in cases where it is known not to be required.
+.PP
+Either
+.I node
+or
+.IR service ,
+but not both, may be NULL.
+.PP
+The
+.BR getaddrinfo ()
+function allocates and initializes a linked list of
+.I addrinfo
+structures, one for each network address that matches
+.I node
+and
+.IR service ,
+subject to any restrictions imposed by
+.IR hints ,
+and returns a pointer to the start of the list in
+.IR res .
+The items in the linked list are linked by the
+.I ai_next
+field.
+.PP
+There are several reasons why
+the linked list may have more than one
+.I addrinfo
+structure, including: the network host is multihomed, accessible
+over multiple protocols (e.g., both
+.B AF_INET
+and
+.BR AF_INET6 );
+or the same service is available from multiple socket types (one
+.B SOCK_STREAM
+address and another
+.B SOCK_DGRAM
+address, for example).
+Normally, the application should try
+using the addresses in the order in which they are returned.
+The sorting function used within
+.BR getaddrinfo ()
+is defined in RFC\ 3484; the order can be tweaked for a particular
+system by editing
+.I /etc/gai.conf
+(available since glibc 2.5).
+.PP
+If
+.I hints.ai_flags
+includes the
+.B AI_CANONNAME
+flag, then the
+.I ai_canonname
+field of the first of the
+.I addrinfo
+structures in the returned list is set to point to the
+official name of the host.
+.\" Prior to glibc 2.3.4, the ai_canonname of each addrinfo
+.\" structure was set pointing to the canonical name; that was
+.\" more than POSIX.1-2001 specified, or other implementations provided.
+.\" MTK, Aug 05
+.PP
+The remaining fields of each returned
+.I addrinfo
+structure are initialized as follows:
+.IP \[bu] 3
+The
+.IR ai_family ,
+.IR ai_socktype ,
+and
+.I ai_protocol
+fields return the socket creation parameters (i.e., these fields have
+the same meaning as the corresponding arguments of
+.BR socket (2)).
+For example,
+.I ai_family
+might return
+.B AF_INET
+or
+.BR AF_INET6 ;
+.I ai_socktype
+might return
+.B SOCK_DGRAM
+or
+.BR SOCK_STREAM ;
+and
+.I ai_protocol
+returns the protocol for the socket.
+.IP \[bu]
+A pointer to the socket address is placed in the
+.I ai_addr
+field, and the length of the socket address, in bytes,
+is placed in the
+.I ai_addrlen
+field.
+.PP
+If
+.I hints.ai_flags
+includes the
+.B AI_ADDRCONFIG
+flag, then IPv4 addresses are returned in the list pointed to by
+.I res
+only if the local system has at least one
+IPv4 address configured, and IPv6 addresses are returned
+only if the local system has at least one IPv6 address configured.
+The loopback address is not considered for this case as valid
+as a configured address.
+This flag is useful on, for example,
+IPv4-only systems, to ensure that
+.BR getaddrinfo ()
+does not return IPv6 socket addresses that would always fail in
+.BR connect (2)
+or
+.BR bind (2).
+.PP
+If
+.I hints.ai_flags
+specifies the
+.B AI_V4MAPPED
+flag, and
+.I hints.ai_family
+was specified as
+.BR AF_INET6 ,
+and no matching IPv6 addresses could be found,
+then return IPv4-mapped IPv6 addresses in the list pointed to by
+.IR res .
+If both
+.B AI_V4MAPPED
+and
+.B AI_ALL
+are specified in
+.IR hints.ai_flags ,
+then return both IPv6 and IPv4-mapped IPv6 addresses
+in the list pointed to by
+.IR res .
+.B AI_ALL
+is ignored if
+.B AI_V4MAPPED
+is not also specified.
+.PP
+The
+.BR freeaddrinfo ()
+function frees the memory that was allocated
+for the dynamically allocated linked list
+.IR res .
+.SS Extensions to getaddrinfo() for Internationalized Domain Names
+Starting with glibc 2.3.4,
+.BR getaddrinfo ()
+has been extended to selectively allow the incoming and outgoing
+hostnames to be transparently converted to and from the
+Internationalized Domain Name (IDN) format (see RFC 3490,
+.IR "Internationalizing Domain Names in Applications (IDNA)" ).
+Four new flags are defined:
+.TP
+.B AI_IDN
+If this flag is specified, then the node name given in
+.I node
+is converted to IDN format if necessary.
+The source encoding is that of the current locale.
+.IP
+If the input name contains non-ASCII characters, then the IDN encoding
+is used.
+Those parts of the node name (delimited by dots) that contain
+non-ASCII characters are encoded using ASCII Compatible Encoding (ACE)
+before being passed to the name resolution functions.
+.\" Implementation Detail:
+.\" To minimize effects on system performance the implementation might
+.\" want to check whether the input string contains any non-ASCII
+.\" characters. If there are none the IDN step can be skipped completely.
+.\" On systems which allow not-ASCII safe encodings for a locale this
+.\" might be a problem.
+.TP
+.B AI_CANONIDN
+After a successful name lookup, and if the
+.B AI_CANONNAME
+flag was specified,
+.BR getaddrinfo ()
+will return the canonical name of the
+node corresponding to the
+.I addrinfo
+structure value passed back.
+The return value is an exact copy of the value returned by the name
+resolution function.
+.IP
+If the name is encoded using ACE, then it will contain the
+.I xn\-\-
+prefix for one or more components of the name.
+To convert these components into a readable form the
+.B AI_CANONIDN
+flag can be passed in addition to
+.BR AI_CANONNAME .
+The resulting string is encoded using the current locale's encoding.
+.\"
+.\"Implementation Detail:
+.\"If no component of the returned name starts with xn\-\- the IDN
+.\"step can be skipped, therefore avoiding unnecessary slowdowns.
+.TP
+.BR AI_IDN_ALLOW_UNASSIGNED ", " AI_IDN_USE_STD3_ASCII_RULES
+Setting these flags will enable the
+IDNA_ALLOW_UNASSIGNED (allow unassigned Unicode code points) and
+IDNA_USE_STD3_ASCII_RULES (check output to make sure it is a STD3
+conforming hostname)
+flags respectively to be used in the IDNA handling.
+.SH RETURN VALUE
+.\" FIXME glibc defines the following additional errors, some which
+.\" can probably be returned by getaddrinfo(); they need to
+.\" be documented.
+.\" #ifdef __USE_GNU
+.\" #define EAI_INPROGRESS -100 /* Processing request in progress. */
+.\" #define EAI_CANCELED -101 /* Request canceled. */
+.\" #define EAI_NOTCANCELED -102 /* Request not canceled. */
+.\" #define EAI_ALLDONE -103 /* All requests done. */
+.\" #define EAI_INTR -104 /* Interrupted by a signal. */
+.\" #define EAI_IDN_ENCODE -105 /* IDN encoding failed. */
+.\" #endif
+.BR getaddrinfo ()
+returns 0 if it succeeds, or one of the following nonzero error codes:
+.TP
+.B EAI_ADDRFAMILY
+.\" Not in SUSv3
+The specified network host does not have any network addresses in the
+requested address family.
+.TP
+.B EAI_AGAIN
+The name server returned a temporary failure indication.
+Try again later.
+.TP
+.B EAI_BADFLAGS
+.I hints.ai_flags
+contains invalid flags; or,
+.I hints.ai_flags
+included
+.B AI_CANONNAME
+and
+.I name
+was NULL.
+.TP
+.B EAI_FAIL
+The name server returned a permanent failure indication.
+.TP
+.B EAI_FAMILY
+The requested address family is not supported.
+.TP
+.B EAI_MEMORY
+Out of memory.
+.TP
+.B EAI_NODATA
+.\" Not in SUSv3
+The specified network host exists, but does not have any
+network addresses defined.
+.TP
+.B EAI_NONAME
+The
+.I node
+or
+.I service
+is not known; or both
+.I node
+and
+.I service
+are NULL; or
+.B AI_NUMERICSERV
+was specified in
+.I hints.ai_flags
+and
+.I service
+was not a numeric port-number string.
+.TP
+.B EAI_SERVICE
+The requested service is not available for the requested socket type.
+It may be available through another socket type.
+For example, this error could occur if
+.I service
+was "shell" (a service available only on stream sockets), and either
+.I hints.ai_protocol
+was
+.BR IPPROTO_UDP ,
+or
+.I hints.ai_socktype
+was
+.BR SOCK_DGRAM ;
+or the error could occur if
+.I service
+was not NULL, and
+.I hints.ai_socktype
+was
+.B SOCK_RAW
+(a socket type that does not support the concept of services).
+.TP
+.B EAI_SOCKTYPE
+The requested socket type is not supported.
+This could occur, for example, if
+.I hints.ai_socktype
+and
+.I hints.ai_protocol
+are inconsistent (e.g.,
+.B SOCK_DGRAM
+and
+.BR IPPROTO_TCP ,
+respectively).
+.TP
+.B EAI_SYSTEM
+Other system error;
+.I errno
+is set to indicate the error.
+.PP
+The
+.BR gai_strerror ()
+function translates these error codes to a human readable string,
+suitable for error reporting.
+.SH FILES
+.I /etc/gai.conf
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR getaddrinfo ()
+T} Thread safety MT-Safe env locale
+T{
+.na
+.nh
+.BR freeaddrinfo (),
+.BR gai_strerror ()
+T} Thread safety MT-Safe
+.TE
+.sp 1
+.SH VERSIONS
+According to POSIX.1, specifying
+.\" POSIX.1-2001, POSIX.1-2008
+.I hints
+as NULL should cause
+.I ai_flags
+to be assumed as 0.
+The GNU C library instead assumes a value of
+.B (AI_V4MAPPED\~|\~AI_ADDRCONFIG)
+for this case,
+since this value is considered an improvement on the specification.
+.SH STANDARDS
+POSIX.1-2008.
+.TP
+.BR getaddrinfo ()
+RFC\ 2553.
+.SH HISTORY
+POSIX.1-2001.
+.TP
+.B AI_ADDRCONFIG
+.TQ
+.B AI_ALL
+.TQ
+.B AI_V4MAPPED
+glibc 2.3.3.
+.TP
+.B AI_NUMERICSERV
+glibc 2.3.4.
+.SH NOTES
+.BR getaddrinfo ()
+supports the
+.IB address % scope-id
+notation for specifying the IPv6 scope-ID.
+.SH EXAMPLES
+.\" getnameinfo.3 refers to this example
+.\" socket.2 refers to this example
+.\" bind.2 refers to this example
+.\" connect.2 refers to this example
+.\" recvfrom.2 refers to this example
+.\" sendto.2 refers to this example
+The following programs demonstrate the use of
+.BR getaddrinfo (),
+.BR gai_strerror (),
+.BR freeaddrinfo (),
+and
+.BR getnameinfo (3).
+The programs are an echo server and client for UDP datagrams.
+.SS Server program
+\&
+.\" SRC BEGIN (server.c)
+.EX
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+\&
+#define BUF_SIZE 500
+\&
+int
+main(int argc, char *argv[])
+{
+ int sfd, s;
+ char buf[BUF_SIZE];
+ ssize_t nread;
+ socklen_t peer_addrlen;
+ struct addrinfo hints;
+ struct addrinfo *result, *rp;
+ struct sockaddr_storage peer_addr;
+\&
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s port\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
+ hints.ai_protocol = 0; /* Any protocol */
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+\&
+ s = getaddrinfo(NULL, argv[1], &hints, &result);
+ if (s != 0) {
+ fprintf(stderr, "getaddrinfo: %s\en", gai_strerror(s));
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* getaddrinfo() returns a list of address structures.
+ Try each address until we successfully bind(2).
+ If socket(2) (or bind(2)) fails, we (close the socket
+ and) try the next address. */
+\&
+ for (rp = result; rp != NULL; rp = rp\->ai_next) {
+ sfd = socket(rp\->ai_family, rp\->ai_socktype,
+ rp\->ai_protocol);
+ if (sfd == \-1)
+ continue;
+\&
+ if (bind(sfd, rp\->ai_addr, rp\->ai_addrlen) == 0)
+ break; /* Success */
+\&
+ close(sfd);
+ }
+\&
+ freeaddrinfo(result); /* No longer needed */
+\&
+ if (rp == NULL) { /* No address succeeded */
+ fprintf(stderr, "Could not bind\en");
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Read datagrams and echo them back to sender. */
+\&
+ for (;;) {
+ char host[NI_MAXHOST], service[NI_MAXSERV];
+\&
+ peer_addrlen = sizeof(peer_addr);
+ nread = recvfrom(sfd, buf, BUF_SIZE, 0,
+ (struct sockaddr *) &peer_addr, &peer_addrlen);
+ if (nread == \-1)
+ continue; /* Ignore failed request */
+\&
+ s = getnameinfo((struct sockaddr *) &peer_addr,
+ peer_addrlen, host, NI_MAXHOST,
+ service, NI_MAXSERV, NI_NUMERICSERV);
+ if (s == 0)
+ printf("Received %zd bytes from %s:%s\en",
+ nread, host, service);
+ else
+ fprintf(stderr, "getnameinfo: %s\en", gai_strerror(s));
+\&
+ if (sendto(sfd, buf, nread, 0, (struct sockaddr *) &peer_addr,
+ peer_addrlen) != nread)
+ {
+ fprintf(stderr, "Error sending response\en");
+ }
+ }
+}
+.EE
+.\" SRC END
+.SS Client program
+\&
+.\" SRC BEGIN (client.c)
+.EX
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+\&
+#define BUF_SIZE 500
+\&
+int
+main(int argc, char *argv[])
+{
+ int sfd, s;
+ char buf[BUF_SIZE];
+ size_t len;
+ ssize_t nread;
+ struct addrinfo hints;
+ struct addrinfo *result, *rp;
+\&
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s host port msg...\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Obtain address(es) matching host/port. */
+\&
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0; /* Any protocol */
+\&
+ s = getaddrinfo(argv[1], argv[2], &hints, &result);
+ if (s != 0) {
+ fprintf(stderr, "getaddrinfo: %s\en", gai_strerror(s));
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* getaddrinfo() returns a list of address structures.
+ Try each address until we successfully connect(2).
+ If socket(2) (or connect(2)) fails, we (close the socket
+ and) try the next address. */
+\&
+ for (rp = result; rp != NULL; rp = rp\->ai_next) {
+ sfd = socket(rp\->ai_family, rp\->ai_socktype,
+ rp\->ai_protocol);
+ if (sfd == \-1)
+ continue;
+\&
+ if (connect(sfd, rp\->ai_addr, rp\->ai_addrlen) != \-1)
+ break; /* Success */
+\&
+ close(sfd);
+ }
+\&
+ freeaddrinfo(result); /* No longer needed */
+\&
+ if (rp == NULL) { /* No address succeeded */
+ fprintf(stderr, "Could not connect\en");
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Send remaining command\-line arguments as separate
+ datagrams, and read responses from server. */
+\&
+ for (size_t j = 3; j < argc; j++) {
+ len = strlen(argv[j]) + 1;
+ /* +1 for terminating null byte */
+\&
+ if (len > BUF_SIZE) {
+ fprintf(stderr,
+ "Ignoring long message in argument %zu\en", j);
+ continue;
+ }
+\&
+ if (write(sfd, argv[j], len) != len) {
+ fprintf(stderr, "partial/failed write\en");
+ exit(EXIT_FAILURE);
+ }
+\&
+ nread = read(sfd, buf, BUF_SIZE);
+ if (nread == \-1) {
+ perror("read");
+ exit(EXIT_FAILURE);
+ }
+\&
+ printf("Received %zd bytes: %s\en", nread, buf);
+ }
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.\" .BR getipnodebyaddr (3),
+.\" .BR getipnodebyname (3),
+.BR getaddrinfo_a (3),
+.BR gethostbyname (3),
+.BR getnameinfo (3),
+.BR inet (3),
+.BR gai.conf (5),
+.BR hostname (7),
+.BR ip (7)