aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c')
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c b/gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c
new file mode 100644
index 0000000..66398e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c
@@ -0,0 +1,119 @@
+/* Example from getaddrinfo.3 manpage, which has this license:
+
+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>
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Since the Linux kernel and libraries are constantly changing, this
+manual page may be incorrect or out-of-date. The author(s) assume no
+responsibility for errors or omissions, or for damages resulting from
+the use of the information contained herein. The author(s) may not
+have taken the same level of care in the production of this manual,
+which is licensed free of charge, as they might when working
+professionally.
+
+Formatted or processed versions of this manual, if unaccompanied by
+the source, must acknowledge the copyright and authors of this work.
+*/
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#define BUF_SIZE 500
+
+int
+main(int argc, char *argv[])
+{
+ struct addrinfo hints;
+ struct addrinfo *result, *rp;
+ int sfd, s;
+ struct sockaddr_storage peer_addr;
+ socklen_t peer_addr_len;
+ ssize_t nread;
+ char buf[BUF_SIZE];
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s port\n", 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\n", 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\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Read datagrams and echo them back to sender. */
+
+ for (;;) {
+ peer_addr_len = sizeof(peer_addr);
+ nread = recvfrom(sfd, buf, BUF_SIZE, 0,
+ (struct sockaddr *) &peer_addr, &peer_addr_len);
+ if (nread == -1)
+ continue; /* Ignore failed request */
+
+ char host[NI_MAXHOST], service[NI_MAXSERV];
+
+ s = getnameinfo((struct sockaddr *) &peer_addr,
+ peer_addr_len, host, NI_MAXHOST,
+ service, NI_MAXSERV, NI_NUMERICSERV);
+ if (s == 0)
+ printf("Received %zd bytes from %s:%s\n",
+ nread, host, service);
+ else
+ fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
+
+ if (sendto(sfd, buf, nread, 0,
+ (struct sockaddr *) &peer_addr,
+ peer_addr_len) != nread)
+ fprintf(stderr, "Error sending response\n");
+ }
+}