(root)/
glibc-2.38/
misc/
tst-preadvwritev2-common.c
       1  /* Common function for preadv2 and pwritev2 tests.
       2     Copyright (C) 2017-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  #include <limits.h>
      20  #include <support/check.h>
      21  
      22  #ifndef RWF_HIPRI
      23  # define RWF_HIPRI 0
      24  #endif
      25  #ifndef RWF_DSYNC
      26  # define RWF_DSYNC 0
      27  #endif
      28  #ifndef RWF_SYNC
      29  # define RWF_SYNC 0
      30  #endif
      31  #ifndef RWF_NOWAIT
      32  # define RWF_NOWAIT 0
      33  #endif
      34  #ifndef RWF_APPEND
      35  # define RWF_APPEND 0
      36  #endif
      37  #define RWF_SUPPORTED	(RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \
      38  			 | RWF_APPEND)
      39  
      40  /* Generic uio_lim.h does not define IOV_MAX.  */
      41  #ifndef IOV_MAX
      42  # define IOV_MAX 1024
      43  #endif
      44  
      45  static void
      46  do_test_with_invalid_fd (void)
      47  {
      48    char buf[256];
      49    struct iovec iov = { buf, sizeof buf };
      50  
      51    /* Check with flag being 0 to use the fallback code which calls pwritev
      52       or writev.  */
      53    TEST_VERIFY (preadv2 (-1, &iov, 1, -1, 0) == -1);
      54    TEST_COMPARE (errno, EBADF);
      55    TEST_VERIFY (pwritev2 (-1, &iov, 1, -1, 0) == -1);
      56    TEST_COMPARE (errno, EBADF);
      57  
      58    /* Same tests as before but with flags being different than 0.  Since
      59       there is no emulation for any flag value, fallback code returns
      60       ENOTSUP.  This is different running on a kernel with preadv2/pwritev2
      61       support, where EBADF is returned).  */
      62    TEST_VERIFY (preadv2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
      63    TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
      64    TEST_VERIFY (pwritev2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
      65    TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
      66  }
      67  
      68  static void
      69  do_test_with_invalid_iov (void)
      70  {
      71    {
      72      char buf[256];
      73      struct iovec iov;
      74  
      75      iov.iov_base = buf;
      76      iov.iov_len = (size_t)SSIZE_MAX + 1;
      77  
      78      TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1);
      79      TEST_COMPARE (errno, EINVAL);
      80      TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1);
      81      TEST_COMPARE (errno, EINVAL);
      82  
      83      /* Same as for invalid file descriptor tests, emulation fallback
      84         first checks for flag value and return ENOTSUP.  */
      85      TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
      86      TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
      87      TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
      88      TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
      89    }
      90  
      91    {
      92      /* An invalid iovec buffer should trigger an invalid memory access
      93         or an error (Linux for instance returns EFAULT).  */
      94      struct iovec iov[IOV_MAX+1] = { 0 };
      95  
      96      TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
      97      TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
      98      TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
      99      TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
     100    }
     101  }
     102  
     103  static void
     104  do_test_with_invalid_flags (void)
     105  {
     106    /* Set the next bit from the mask of all supported flags.  */
     107    int invalid_flag = RWF_SUPPORTED != 0 ? __builtin_clz (RWF_SUPPORTED) : 2;
     108    invalid_flag = 0x1 << ((sizeof (int) * CHAR_BIT) - invalid_flag);
     109  
     110    char buf[32];
     111    const struct iovec vec = { .iov_base = buf, .iov_len = sizeof (buf) };
     112    if (preadv2 (temp_fd, &vec, 1, 0, invalid_flag) != -1)
     113      FAIL_EXIT1 ("preadv2 did not fail with an invalid flag");
     114    if (errno != ENOTSUP)
     115      FAIL_EXIT1 ("preadv2 failure did not set errno to ENOTSUP (%d)", errno);
     116  
     117    /* This might fail for compat syscall (32 bits running on 64 bits kernel)
     118       due a kernel issue.  */
     119    if (pwritev2 (temp_fd, &vec, 1, 0, invalid_flag) != -1)
     120      FAIL_EXIT1 ("pwritev2 did not fail with an invalid flag");
     121    if (errno != ENOTSUP)
     122      FAIL_EXIT1 ("pwritev2 failure did not set errno to ENOTSUP (%d)", errno);
     123  }