(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
fd-glibc-byte-stream-connection-server.c
       1  /* Example from glibc manual (16.9.7).  */
       2  /* { dg-require-effective-target sockets } */
       3  /* { dg-additional-options "-Wno-analyzer-too-complex" } */
       4  
       5  #include <stdio.h>
       6  #include <errno.h>
       7  #include <stdlib.h>
       8  #include <unistd.h>
       9  #include <sys/types.h>
      10  #include <sys/socket.h>
      11  #include <netinet/in.h>
      12  #include <arpa/inet.h>
      13  #include <netdb.h>
      14  
      15  #define PORT    5555
      16  #define MAXMSG  512
      17  
      18  int
      19  make_socket (uint16_t port)
      20  {
      21    int sock;
      22    struct sockaddr_in name;
      23  
      24    /* Create the socket. */
      25    sock = socket (PF_INET, SOCK_STREAM, 0);
      26    if (sock < 0)
      27      {
      28        perror ("socket");
      29        exit (EXIT_FAILURE);
      30      }
      31  
      32    /* Give the socket a name. */
      33    name.sin_family = AF_INET;
      34    name.sin_port = htons (port);
      35    name.sin_addr.s_addr = htonl (INADDR_ANY);
      36    if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
      37      {
      38        perror ("bind");
      39        exit (EXIT_FAILURE);
      40      }
      41  
      42    return sock;
      43  }
      44  
      45  int
      46  read_from_client (int filedes)
      47  {
      48    char buffer[MAXMSG];
      49    int nbytes;
      50  
      51    nbytes = read (filedes, buffer, MAXMSG);
      52    if (nbytes < 0)
      53      {
      54        /* Read error. */
      55        perror ("read");
      56        exit (EXIT_FAILURE);
      57      }
      58    else if (nbytes == 0)
      59      /* End-of-file. */
      60      return -1;
      61    else
      62      {
      63        /* Data read. */
      64        fprintf (stderr, "Server: got message: `%s'\n", buffer);
      65        return 0;
      66      }
      67  }
      68  
      69  int
      70  main (void)
      71  {
      72    int sock;
      73    fd_set active_fd_set, read_fd_set;
      74    int i;
      75    struct sockaddr_in clientname;
      76    socklen_t size;
      77  
      78    /* Create the socket and set it up to accept connections. */
      79    sock = make_socket (PORT);
      80    if (listen (sock, 1) < 0)
      81      {
      82        perror ("listen");
      83        exit (EXIT_FAILURE);
      84      }
      85  
      86    /* Initialize the set of active sockets. */
      87    FD_ZERO (&active_fd_set);
      88    FD_SET (sock, &active_fd_set);
      89  
      90    while (1)
      91      {
      92        /* Block until input arrives on one or more active sockets. */
      93        read_fd_set = active_fd_set;
      94        if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
      95          {
      96            perror ("select");
      97            exit (EXIT_FAILURE);
      98          }
      99  
     100        /* Service all the sockets with input pending. */
     101        for (i = 0; i < FD_SETSIZE; ++i)
     102          if (FD_ISSET (i, &read_fd_set))
     103            {
     104              if (i == sock)
     105                {
     106                  /* Connection request on original socket. */
     107                  int new;
     108                  size = sizeof (clientname);
     109                  new = accept (sock,
     110                                (struct sockaddr *) &clientname,
     111                                &size);
     112                  if (new < 0)
     113                    {
     114                      perror ("accept");
     115                      exit (EXIT_FAILURE);
     116                    }
     117                  fprintf (stderr,
     118                           "Server: connect from host %s, port %hd.\n",
     119                           inet_ntoa (clientname.sin_addr),
     120                           ntohs (clientname.sin_port));
     121                  FD_SET (new, &active_fd_set);
     122                }
     123              else
     124                {
     125                  /* Data arriving on an already-connected socket. */
     126                  if (read_from_client (i) < 0)
     127                    {
     128                      close (i);
     129                      FD_CLR (i, &active_fd_set);
     130                    }
     131                }
     132            }
     133      }
     134  }