/* Tests for socket address type definitions.
   Copyright (C) 2016-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation; either version 2.1 of the
   License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If
   not, see <http://www.gnu.org/licenses/>.  */

#include <netinet/in.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>

/* This is a copy of the previous definition of struct
   sockaddr_storage.  It is not equal to the old value of _SS_SIZE
   (128) on all architectures.  We must stay compatible with the old
   definition.  */

#define OLD_REFERENCE_SIZE 128
#define OLD_PADSIZE (OLD_REFERENCE_SIZE - (2 * sizeof (__ss_aligntype)))
struct sockaddr_storage_old
  {
    __SOCKADDR_COMMON (old_);
    __ss_aligntype old_align;
    char old_padding[OLD_PADSIZE];
  };

static bool errors;

static void
check (bool ok, const char *message)
{
  if (!ok)
    {
      printf ("error: failed check: %s\n", message);
      errors = true;
    }
}

static int
do_test (void)
{
  check (OLD_REFERENCE_SIZE >= _SS_SIZE,
         "old target size is not smaller than actual size");
  check (sizeof (struct sockaddr_storage_old)
         == sizeof (struct sockaddr_storage),
         "old and new sizes match");
  check (__alignof (struct sockaddr_storage_old)
         == __alignof (struct sockaddr_storage),
         "old and new alignment matches");
  check (offsetof (struct sockaddr_storage_old, old_family)
         == offsetof (struct sockaddr_storage, ss_family),
         "old and new family offsets match");
  check (sizeof (struct sockaddr_storage) == _SS_SIZE,
         "struct sockaddr_storage size");

  /* Check for lack of holes in the struct definition.   */
  check (offsetof (struct sockaddr_storage, __ss_padding)
         == __SOCKADDR_COMMON_SIZE,
         "implicit padding before explicit padding");
  check (offsetof (struct sockaddr_storage, __ss_align)
         == __SOCKADDR_COMMON_SIZE
           + sizeof (((struct sockaddr_storage) {}).__ss_padding),
         "implicit padding before explicit padding");

  /* Check for POSIX compatibility requirements between struct
     sockaddr_storage and struct sockaddr_un.  */
  check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_un),
         "sockaddr_storage is at least as large as sockaddr_un");
  check (__alignof (struct sockaddr_storage)
         >= __alignof (struct sockaddr_un),
         "sockaddr_storage is at least as aligned as sockaddr_un");
  check (offsetof (struct sockaddr_storage, ss_family)
         == offsetof (struct sockaddr_un, sun_family),
         "family offsets match");

  /* Check that the compiler preserves bit patterns in aggregate
     copies.  Based on <https://gcc.gnu.org/PR71120>.  */
  check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_in),
         "sockaddr_storage is at least as large as sockaddr_in");
  {
    struct sockaddr_storage addr;
    memset (&addr, 0, sizeof (addr));
    {
      struct sockaddr_in *sinp = (struct sockaddr_in *)&addr;
      sinp->sin_family = AF_INET;
      sinp->sin_addr.s_addr = htonl (INADDR_LOOPBACK);
      sinp->sin_port = htons (80);
    }
    struct sockaddr_storage copy;
    copy = addr;

    struct sockaddr_storage *p = malloc (sizeof (*p));
    if (p == NULL)
      {
        printf ("error: malloc: %m\n");
        return 1;
      }
    *p = copy;
    const struct sockaddr_in *sinp = (const struct sockaddr_in *)p;
    check (sinp->sin_family == AF_INET, "sin_family");
    check (sinp->sin_addr.s_addr == htonl (INADDR_LOOPBACK), "sin_addr");
    check (sinp->sin_port == htons (80), "sin_port");
    free (p);
  }

  return errors;
}

#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
