tst-preadvwritev2-common.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /* Common function for preadv2 and pwritev2 tests.
  2. Copyright (C) 2017-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <limits.h>
  16. #include <support/check.h>
  17. #ifndef RWF_HIPRI
  18. # define RWF_HIPRI 0
  19. #endif
  20. #ifndef RWF_DSYNC
  21. # define RWF_DSYNC 0
  22. #endif
  23. #ifndef RWF_SYNC
  24. # define RWF_SYNC 0
  25. #endif
  26. #ifndef RWF_NOWAIT
  27. # define RWF_NOWAIT 0
  28. #endif
  29. #ifndef RWF_APPEND
  30. # define RWF_APPEND 0
  31. #endif
  32. #ifndef RWF_NOAPPEND
  33. # define RWF_NOAPPEND 0
  34. #endif
  35. #ifndef RWF_ATOMIC
  36. # define RWF_ATOMIC 0
  37. #endif
  38. #ifndef RWF_DONTCACHE
  39. # define RWF_DONTCACHE 0
  40. #endif
  41. #define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \
  42. | RWF_APPEND | RWF_NOAPPEND | RWF_ATOMIC \
  43. | RWF_DONTCACHE)
  44. /* Generic uio_lim.h does not define IOV_MAX. */
  45. #ifndef IOV_MAX
  46. # define IOV_MAX 1024
  47. #endif
  48. static void
  49. do_test_with_invalid_fd (void)
  50. {
  51. char buf[256];
  52. struct iovec iov = { buf, sizeof buf };
  53. /* Check with flag being 0 to use the fallback code which calls pwritev
  54. or writev. */
  55. TEST_VERIFY (preadv2 (-1, &iov, 1, -1, 0) == -1);
  56. TEST_COMPARE (errno, EBADF);
  57. TEST_VERIFY (pwritev2 (-1, &iov, 1, -1, 0) == -1);
  58. TEST_COMPARE (errno, EBADF);
  59. /* Same tests as before but with flags being different than 0. Since
  60. there is no emulation for any flag value, fallback code returns
  61. ENOTSUP. This is different running on a kernel with preadv2/pwritev2
  62. support, where EBADF is returned). */
  63. TEST_VERIFY (preadv2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
  64. TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
  65. TEST_VERIFY (pwritev2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
  66. TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
  67. }
  68. static void
  69. do_test_with_invalid_iov (void)
  70. {
  71. {
  72. char buf[256];
  73. struct iovec iov;
  74. iov.iov_base = buf;
  75. iov.iov_len = (size_t)SSIZE_MAX + 1;
  76. TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1);
  77. TEST_COMPARE (errno, EINVAL);
  78. TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1);
  79. TEST_COMPARE (errno, EINVAL);
  80. /* Same as for invalid file descriptor tests, emulation fallback
  81. first checks for flag value and return ENOTSUP. */
  82. TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
  83. TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
  84. TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
  85. TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
  86. }
  87. {
  88. /* An invalid iovec buffer should trigger an invalid memory access
  89. or an error (Linux for instance returns EFAULT). */
  90. struct iovec iov[IOV_MAX+1] = { };
  91. TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
  92. TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
  93. TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
  94. TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
  95. }
  96. }
  97. static void
  98. do_test_with_invalid_flags (void)
  99. {
  100. /* Set all the bits that are not used by the supported flags. */
  101. int invalid_flag = ~RWF_SUPPORTED;
  102. char buf[32];
  103. const struct iovec vec = { .iov_base = buf, .iov_len = sizeof (buf) };
  104. if (preadv2 (temp_fd, &vec, 1, 0, invalid_flag) != -1)
  105. FAIL_EXIT1 ("preadv2 did not fail with an invalid flag");
  106. if (errno != ENOTSUP)
  107. FAIL_EXIT1 ("preadv2 failure did not set errno to ENOTSUP (%d)", errno);
  108. /* This might fail for compat syscall (32 bits running on 64 bits kernel)
  109. due a kernel issue. */
  110. if (pwritev2 (temp_fd, &vec, 1, 0, invalid_flag) != -1)
  111. FAIL_EXIT1 ("pwritev2 did not fail with an invalid flag");
  112. if (errno != ENOTSUP)
  113. FAIL_EXIT1 ("pwritev2 failure did not set errno to ENOTSUP (%d)", errno);
  114. }