(root)/
glibc-2.38/
inet/
tst-sockaddr.c
       1  /* Tests for socket address type definitions.
       2     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; see the file COPYING.LIB.  If
      17     not, see <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <netinet/in.h>
      20  #include <stdbool.h>
      21  #include <stddef.h>
      22  #include <stdio.h>
      23  #include <stdlib.h>
      24  #include <string.h>
      25  #include <sys/socket.h>
      26  #include <sys/un.h>
      27  
      28  /* This is a copy of the previous definition of struct
      29     sockaddr_storage.  It is not equal to the old value of _SS_SIZE
      30     (128) on all architectures.  We must stay compatible with the old
      31     definition.  */
      32  
      33  #define OLD_REFERENCE_SIZE 128
      34  #define OLD_PADSIZE (OLD_REFERENCE_SIZE - (2 * sizeof (__ss_aligntype)))
      35  struct sockaddr_storage_old
      36    {
      37      __SOCKADDR_COMMON (old_);
      38      __ss_aligntype old_align;
      39      char old_padding[OLD_PADSIZE];
      40    };
      41  
      42  static bool errors;
      43  
      44  static void
      45  check (bool ok, const char *message)
      46  {
      47    if (!ok)
      48      {
      49        printf ("error: failed check: %s\n", message);
      50        errors = true;
      51      }
      52  }
      53  
      54  static int
      55  do_test (void)
      56  {
      57    check (OLD_REFERENCE_SIZE >= _SS_SIZE,
      58           "old target size is not smaller than actual size");
      59    check (sizeof (struct sockaddr_storage_old)
      60           == sizeof (struct sockaddr_storage),
      61           "old and new sizes match");
      62    check (__alignof (struct sockaddr_storage_old)
      63           == __alignof (struct sockaddr_storage),
      64           "old and new alignment matches");
      65    check (offsetof (struct sockaddr_storage_old, old_family)
      66           == offsetof (struct sockaddr_storage, ss_family),
      67           "old and new family offsets match");
      68    check (sizeof (struct sockaddr_storage) == _SS_SIZE,
      69           "struct sockaddr_storage size");
      70  
      71    /* Check for lack of holes in the struct definition.   */
      72    check (offsetof (struct sockaddr_storage, __ss_padding)
      73           == __SOCKADDR_COMMON_SIZE,
      74           "implicit padding before explicit padding");
      75    check (offsetof (struct sockaddr_storage, __ss_align)
      76           == __SOCKADDR_COMMON_SIZE
      77             + sizeof (((struct sockaddr_storage) {}).__ss_padding),
      78           "implicit padding before explicit padding");
      79  
      80    /* Check for POSIX compatibility requirements between struct
      81       sockaddr_storage and struct sockaddr_un.  */
      82    check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_un),
      83           "sockaddr_storage is at least as large as sockaddr_un");
      84    check (__alignof (struct sockaddr_storage)
      85           >= __alignof (struct sockaddr_un),
      86           "sockaddr_storage is at least as aligned as sockaddr_un");
      87    check (offsetof (struct sockaddr_storage, ss_family)
      88           == offsetof (struct sockaddr_un, sun_family),
      89           "family offsets match");
      90  
      91    /* Check that the compiler preserves bit patterns in aggregate
      92       copies.  Based on <https://gcc.gnu.org/PR71120>.  */
      93    check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_in),
      94           "sockaddr_storage is at least as large as sockaddr_in");
      95    {
      96      struct sockaddr_storage addr;
      97      memset (&addr, 0, sizeof (addr));
      98      {
      99        struct sockaddr_in *sinp = (struct sockaddr_in *)&addr;
     100        sinp->sin_family = AF_INET;
     101        sinp->sin_addr.s_addr = htonl (INADDR_LOOPBACK);
     102        sinp->sin_port = htons (80);
     103      }
     104      struct sockaddr_storage copy;
     105      copy = addr;
     106  
     107      struct sockaddr_storage *p = malloc (sizeof (*p));
     108      if (p == NULL)
     109        {
     110          printf ("error: malloc: %m\n");
     111          return 1;
     112        }
     113      *p = copy;
     114      const struct sockaddr_in *sinp = (const struct sockaddr_in *)p;
     115      check (sinp->sin_family == AF_INET, "sin_family");
     116      check (sinp->sin_addr.s_addr == htonl (INADDR_LOOPBACK), "sin_addr");
     117      check (sinp->sin_port == htons (80), "sin_port");
     118      free (p);
     119    }
     120  
     121    return errors;
     122  }
     123  
     124  #define TEST_FUNCTION do_test ()
     125  #include "../test-skeleton.c"