tst-preadvwritev2-common.c 4.1 KB

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