1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * 07/2001 Ported by Wayne Boyer 5f08c3bdfSopenharmony_ci * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz> 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci/* 9f08c3bdfSopenharmony_ci * DESCRIPTION 10f08c3bdfSopenharmony_ci * Testcase to check the basic functionality of the readv(2) system call. 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * ALGORITHM 13f08c3bdfSopenharmony_ci * Create a IO vector, and attempt to readv() various components of it. 14f08c3bdfSopenharmony_ci */ 15f08c3bdfSopenharmony_ci#include <stdlib.h> 16f08c3bdfSopenharmony_ci#include <sys/types.h> 17f08c3bdfSopenharmony_ci#include <sys/uio.h> 18f08c3bdfSopenharmony_ci#include <fcntl.h> 19f08c3bdfSopenharmony_ci#include <memory.h> 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_ci#include "tst_test.h" 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_ci/* Note: multi_iovec test assumes CHUNK is divisible by 4 */ 24f08c3bdfSopenharmony_ci#define CHUNK 64 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_cistatic char buf[CHUNK]; 27f08c3bdfSopenharmony_cistatic struct iovec *rd_iovec, *big_iovec, *multi_iovec, *lockup_iovec; 28f08c3bdfSopenharmony_cistatic int fd; 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_cistatic struct testcase { 31f08c3bdfSopenharmony_ci struct iovec **iov; 32f08c3bdfSopenharmony_ci int iov_count, exp_ret; 33f08c3bdfSopenharmony_ci const char *name; 34f08c3bdfSopenharmony_ci} testcase_list[] = { 35f08c3bdfSopenharmony_ci {&rd_iovec, 0, 0, "readv() with 0 I/O vectors"}, 36f08c3bdfSopenharmony_ci {&rd_iovec, 3, CHUNK, "readv() with NULL I/O vectors"}, 37f08c3bdfSopenharmony_ci {&big_iovec, 2, CHUNK, "readv() with too big I/O vectors"}, 38f08c3bdfSopenharmony_ci {&multi_iovec, 2, 3*CHUNK/4, "readv() with multiple I/O vectors"}, 39f08c3bdfSopenharmony_ci {&lockup_iovec, 2, CHUNK, "readv() with zero-len buffer"}, 40f08c3bdfSopenharmony_ci}; 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_cistatic void test_readv(unsigned int n) 43f08c3bdfSopenharmony_ci{ 44f08c3bdfSopenharmony_ci int i, fpos, fail = 0; 45f08c3bdfSopenharmony_ci size_t j; 46f08c3bdfSopenharmony_ci char *ptr; 47f08c3bdfSopenharmony_ci const struct testcase *tc = testcase_list + n; 48f08c3bdfSopenharmony_ci struct iovec *vec; 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci SAFE_LSEEK(fd, 0, SEEK_SET); 51f08c3bdfSopenharmony_ci vec = *tc->iov; 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci for (i = 0; i < tc->iov_count; i++) { 54f08c3bdfSopenharmony_ci if (vec[i].iov_base && vec[i].iov_len) 55f08c3bdfSopenharmony_ci memset(vec[i].iov_base, 0, vec[i].iov_len); 56f08c3bdfSopenharmony_ci } 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci TEST(readv(fd, vec, tc->iov_count)); 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci if (TST_RET == -1) 61f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "readv() failed unexpectedly"); 62f08c3bdfSopenharmony_ci else if (TST_RET < 0) 63f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "readv() returned invalid value"); 64f08c3bdfSopenharmony_ci else if (TST_RET != tc->exp_ret) 65f08c3bdfSopenharmony_ci tst_res(TFAIL, "readv() returned unexpected value %ld", 66f08c3bdfSopenharmony_ci TST_RET); 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci if (TST_RET != tc->exp_ret) 69f08c3bdfSopenharmony_ci return; 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci tst_res(TPASS, "%s", tc->name); 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci for (i = 0, fpos = 0; i < tc->iov_count; i++) { 74f08c3bdfSopenharmony_ci ptr = vec[i].iov_base; 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci for (j = 0; j < vec[i].iov_len; j++, fpos++) { 77f08c3bdfSopenharmony_ci if (ptr[j] != (fpos < tc->exp_ret ? 0x42 : 0)) 78f08c3bdfSopenharmony_ci fail++; 79f08c3bdfSopenharmony_ci } 80f08c3bdfSopenharmony_ci } 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci if (fail) 83f08c3bdfSopenharmony_ci tst_res(TFAIL, "Wrong buffer content"); 84f08c3bdfSopenharmony_ci else 85f08c3bdfSopenharmony_ci tst_res(TPASS, "readv() correctly read %d bytes ", tc->exp_ret); 86f08c3bdfSopenharmony_ci} 87f08c3bdfSopenharmony_ci 88f08c3bdfSopenharmony_cistatic void setup(void) 89f08c3bdfSopenharmony_ci{ 90f08c3bdfSopenharmony_ci /* replace the default NULL pointer with invalid address */ 91f08c3bdfSopenharmony_ci lockup_iovec[0].iov_base = tst_get_bad_addr(NULL); 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_ci memset(buf, 0x42, sizeof(buf)); 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci fd = SAFE_OPEN("data_file", O_WRONLY | O_CREAT | O_TRUNC, 0666); 96f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, sizeof(buf)); 97f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 98f08c3bdfSopenharmony_ci fd = SAFE_OPEN("data_file", O_RDONLY); 99f08c3bdfSopenharmony_ci} 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_cistatic void cleanup(void) 102f08c3bdfSopenharmony_ci{ 103f08c3bdfSopenharmony_ci if (fd >= 0) 104f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 105f08c3bdfSopenharmony_ci} 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_cistatic struct tst_test test = { 108f08c3bdfSopenharmony_ci .setup = setup, 109f08c3bdfSopenharmony_ci .cleanup = cleanup, 110f08c3bdfSopenharmony_ci .test = test_readv, 111f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(testcase_list), 112f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 113f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 114f08c3bdfSopenharmony_ci {"linux-git", "19f18459330f"}, 115f08c3bdfSopenharmony_ci {} 116f08c3bdfSopenharmony_ci }, 117f08c3bdfSopenharmony_ci .bufs = (struct tst_buffers[]) { 118f08c3bdfSopenharmony_ci {&rd_iovec, .iov_sizes = (int[]){CHUNK, 0, 0, -1}}, 119f08c3bdfSopenharmony_ci {&big_iovec, .iov_sizes = (int[]){2*CHUNK, CHUNK, -1}}, 120f08c3bdfSopenharmony_ci {&multi_iovec, .iov_sizes = (int[]){CHUNK/4, CHUNK/2, -1}}, 121f08c3bdfSopenharmony_ci {&lockup_iovec, .iov_sizes = (int[]){0, CHUNK, -1}}, 122f08c3bdfSopenharmony_ci {} 123f08c3bdfSopenharmony_ci } 124f08c3bdfSopenharmony_ci}; 125