| Elliott Hughes | be57a40 | 2015-06-10 17:24:20 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2015 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include <gtest/gtest.h> | 
|  | 18 |  | 
|  | 19 | #include <sys/uio.h> | 
|  | 20 |  | 
| Mark Salyzyn | 68a3bcc | 2018-11-13 07:35:21 -0800 | [diff] [blame] | 21 | #include <android-base/file.h> | 
| Elliott Hughes | 6f4594d | 2015-08-26 13:27:43 -0700 | [diff] [blame] | 22 |  | 
|  | 23 | TEST(sys_uio, readv_writev) { | 
|  | 24 | TemporaryFile tf; | 
|  | 25 |  | 
|  | 26 | char buf1[] = "hello"; | 
|  | 27 | char buf2[] = "world"; | 
|  | 28 | iovec ios[] = { { buf1, 5 }, { buf2, 5 } }; | 
|  | 29 |  | 
|  | 30 | ASSERT_EQ(10, writev(tf.fd, ios, 2)); | 
|  | 31 |  | 
|  | 32 | ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); | 
|  | 33 |  | 
|  | 34 | memset(buf1, '1', sizeof(buf1)); | 
|  | 35 | memset(buf2, '2', sizeof(buf2)); | 
|  | 36 |  | 
|  | 37 | ASSERT_EQ(10, readv(tf.fd, ios, 2)); | 
|  | 38 | buf1[5] = buf2[5] = '\0'; | 
|  | 39 | ASSERT_STREQ("hello", buf1); | 
|  | 40 | ASSERT_STREQ("world", buf2); | 
|  | 41 | } | 
|  | 42 |  | 
|  | 43 | template <typename ReadFn, typename WriteFn> | 
|  | 44 | void TestPreadVPwriteV(ReadFn read_fn, WriteFn write_fn) { | 
|  | 45 | TemporaryFile tf; | 
|  | 46 |  | 
|  | 47 | char buf[] = "world"; | 
|  | 48 | iovec ios[] = { { buf, 5 } }; | 
|  | 49 |  | 
|  | 50 | ASSERT_EQ(5, write_fn(tf.fd, ios, 1, 5)); | 
|  | 51 | ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_CUR)); | 
|  | 52 |  | 
|  | 53 | strcpy(buf, "hello"); | 
|  | 54 | ASSERT_EQ(5, write_fn(tf.fd, ios, 1, 0)); | 
|  | 55 | ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_CUR)); | 
|  | 56 |  | 
|  | 57 | ASSERT_EQ(5, read_fn(tf.fd, ios, 1, 5)); | 
|  | 58 | ASSERT_STREQ("world", buf); | 
|  | 59 | ASSERT_EQ(5, read_fn(tf.fd, ios, 1, 0)); | 
|  | 60 | ASSERT_STREQ("hello", buf); | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | TEST(sys_uio, preadv_pwritev) { | 
|  | 64 | TestPreadVPwriteV(preadv, pwritev); | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | TEST(sys_uio, preadv64_pwritev64) { | 
|  | 68 | TestPreadVPwriteV(preadv64, pwritev64); | 
|  | 69 | } | 
|  | 70 |  | 
|  | 71 | TEST(sys_uio, process_vm_readv) { | 
| Elliott Hughes | be57a40 | 2015-06-10 17:24:20 -0700 | [diff] [blame] | 72 | ASSERT_EQ(0, process_vm_readv(0, nullptr, 0, nullptr, 0, 0)); | 
| Pavel Labath | cc44100 | 2017-01-12 11:56:39 +0000 | [diff] [blame] | 73 |  | 
|  | 74 | // Test that we can read memory from our own process | 
|  | 75 | char src[1024] = "This is the source buffer containing some data"; | 
|  | 76 | char dst[1024] = ""; | 
|  | 77 | iovec remote = { src, sizeof src }; | 
|  | 78 | iovec local = { dst, sizeof dst }; | 
|  | 79 | ASSERT_EQ(ssize_t(sizeof src), process_vm_readv(getpid(), &local, 1, &remote, 1, 0)); | 
|  | 80 | // Check whether data was copied (in the correct direction) | 
|  | 81 | ASSERT_EQ('T', dst[0]); | 
|  | 82 | ASSERT_EQ(0, memcmp(src, dst, sizeof src)); | 
|  | 83 |  | 
|  | 84 | // Reading from non-allocated memory should return an error | 
|  | 85 | remote = { nullptr, sizeof dst }; | 
|  | 86 | ASSERT_EQ(-1, process_vm_readv(getpid(), &local, 1, &remote, 1, 0)); | 
|  | 87 | ASSERT_EQ(EFAULT, errno); | 
| Elliott Hughes | be57a40 | 2015-06-10 17:24:20 -0700 | [diff] [blame] | 88 | } | 
|  | 89 |  | 
| Elliott Hughes | 6f4594d | 2015-08-26 13:27:43 -0700 | [diff] [blame] | 90 | TEST(sys_uio, process_vm_writev) { | 
| Elliott Hughes | be57a40 | 2015-06-10 17:24:20 -0700 | [diff] [blame] | 91 | ASSERT_EQ(0, process_vm_writev(0, nullptr, 0, nullptr, 0, 0)); | 
| Pavel Labath | cc44100 | 2017-01-12 11:56:39 +0000 | [diff] [blame] | 92 |  | 
|  | 93 | // Test that we can read memory from our own process | 
|  | 94 | char src[1024] = "This is the source buffer containing some data"; | 
|  | 95 | char dst[1024] = ""; | 
|  | 96 | iovec remote = { dst, sizeof dst }; | 
|  | 97 | iovec local = { src, sizeof src }; | 
|  | 98 | ASSERT_EQ(ssize_t(sizeof src), process_vm_writev(getpid(), &local, 1, &remote, 1, 0)); | 
|  | 99 | // Check whether data was copied (in the correct direction) | 
|  | 100 | ASSERT_EQ('T', dst[0]); | 
|  | 101 | ASSERT_EQ(0, memcmp(src, dst, sizeof src)); | 
|  | 102 |  | 
|  | 103 | // Writing to non-allocated memory should return an error | 
|  | 104 | remote = { nullptr, sizeof dst }; | 
|  | 105 | ASSERT_EQ(-1, process_vm_writev(getpid(), &local, 1, &remote, 1, 0)); | 
|  | 106 | ASSERT_EQ(EFAULT, errno); | 
| Elliott Hughes | be57a40 | 2015-06-10 17:24:20 -0700 | [diff] [blame] | 107 | } |