(root)/
glibc-2.38/
socket/
tst-cmsghdr-skeleton.c
       1  /* Test ancillary data header creation.
       2     Copyright (C) 2022-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
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the 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; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  /* We use the preprocessor to generate the function/macro tests instead of
      20     using indirection because having all the macro expansions alongside
      21     each other lets the compiler warn us about suspicious pointer
      22     arithmetic across subsequent CMSG_{FIRST,NXT}HDR expansions.  */
      23  
      24  #include <stdint.h>
      25  
      26  #define RUN_TEST_CONCAT(suffix) run_test_##suffix
      27  #define RUN_TEST_FUNCNAME(suffix) RUN_TEST_CONCAT (suffix)
      28  
      29  static void
      30  RUN_TEST_FUNCNAME (CMSG_NXTHDR_IMPL) (void)
      31  {
      32    struct msghdr m = {0};
      33    struct cmsghdr *cmsg;
      34    char cmsgbuf[3 * CMSG_SPACE (sizeof (PAYLOAD))] = {0};
      35  
      36    m.msg_control = cmsgbuf;
      37    m.msg_controllen = sizeof (cmsgbuf);
      38  
      39    /* First header should point to the start of the buffer.  */
      40    cmsg = CMSG_FIRSTHDR (&m);
      41    TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
      42  
      43    /* If the first header length consumes the entire buffer, there is no
      44       space remaining for additional headers.  */
      45    cmsg->cmsg_len = sizeof (cmsgbuf);
      46    cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
      47    TEST_VERIFY_EXIT (cmsg == NULL);
      48  
      49    /* The first header length is so big, using it would cause an overflow.  */
      50    cmsg = CMSG_FIRSTHDR (&m);
      51    TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
      52    cmsg->cmsg_len = (__typeof (cmsg->cmsg_len)) SIZE_MAX;
      53    cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
      54    TEST_VERIFY_EXIT (cmsg == NULL);
      55  
      56    /* The first header leaves just enough space to hold another header.  */
      57    cmsg = CMSG_FIRSTHDR (&m);
      58    TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
      59    cmsg->cmsg_len = sizeof (cmsgbuf) - sizeof (struct cmsghdr);
      60    cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
      61    TEST_VERIFY_EXIT (cmsg != NULL);
      62  
      63    /* The first header leaves space but not enough for another header.  */
      64    cmsg = CMSG_FIRSTHDR (&m);
      65    TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
      66    cmsg->cmsg_len ++;
      67    cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
      68    TEST_VERIFY_EXIT (cmsg == NULL);
      69  
      70    /* The second header leaves just enough space to hold another header.  */
      71    cmsg = CMSG_FIRSTHDR (&m);
      72    TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
      73    cmsg->cmsg_len = CMSG_LEN (sizeof (PAYLOAD));
      74    cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
      75    TEST_VERIFY_EXIT (cmsg != NULL);
      76    cmsg->cmsg_len = sizeof (cmsgbuf)
      77                     - CMSG_SPACE (sizeof (PAYLOAD)) /* First header.  */
      78                     - sizeof (struct cmsghdr);
      79    cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
      80    TEST_VERIFY_EXIT (cmsg != NULL);
      81  
      82    /* The second header leaves space but not enough for another header.  */
      83    cmsg = CMSG_FIRSTHDR (&m);
      84    TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
      85    cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
      86    TEST_VERIFY_EXIT (cmsg != NULL);
      87    cmsg->cmsg_len ++;
      88    cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
      89    TEST_VERIFY_EXIT (cmsg == NULL);
      90  
      91    return;
      92  }