1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi/native_api.h"
17 #include <cstdio>
18 #include <cstring>
19 #include <fcntl.h>
20 #include <js_native_api.h>
21 #include <js_native_api_types.h>
22 #include <node_api.h>
23 #include <sys/stat.h>
24 #include <sys/uio.h>
25 #include <unistd.h>
26
27 #define PARAM_0 0
28 #define PARAM_1 1
29 #define PARAM_2 2
30 #define PARAM_256 256
31 #define PARAM_0777 0777
32 #define PARAM_UNNORMAL (-1)
33 #define RETURN_0 0
34 #define FAILD (-1)
35 #define ERRON_0 0
36 #define SIZE_10 10
37 #define SIZE_100 100
38 #define SIZE_4096 4096
39 #define SIZE_8192 8192
40 #define TEST_AT_FDCWD (-100)
41 #define TEST_ERROR_AT_FDCWD 100
42
43 #define NO_ERR 0
44 #define SUCCESS 1
45 #define FAIL (-1)
46 #define TEN 10
47 #define TEST_MODE 0666
Readv(napi_env env, napi_callback_info info)48 static napi_value Readv(napi_env env, napi_callback_info info)
49 {
50 size_t argc = 1;
51 napi_value args[1] = {nullptr};
52 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
53
54 int param;
55 napi_get_value_int32(env, args[0], ¶m);
56
57 int ret;
58 if (param == PARAM_UNNORMAL) {
59 ret = readv(PARAM_UNNORMAL, nullptr, PARAM_UNNORMAL);
60 } else {
61 int fd = open("/data/storage/el2/base/files/testReadv.txt", O_RDWR | O_CREAT, PARAM_0777);
62
63 char buf1[] = "testreadv1";
64 char buf2[] = "testreadv2";
65 struct iovec ios[] = {{buf1, strlen(buf1)}, {buf2, strlen(buf2)}};
66 ssize_t value = writev(fd, ios, sizeof(ios) / sizeof(struct iovec));
67 lseek(fd, PARAM_0, SEEK_SET);
68 memset(buf1, PARAM_0, sizeof(buf1));
69 memset(buf2, PARAM_0, sizeof(buf2));
70 value = readv(fd, ios, sizeof(ios) / sizeof(struct iovec));
71 if (value == strlen(buf1) + strlen(buf2)) {
72 ret = RETURN_0;
73 } else {
74 ret = FAIL;
75 }
76 close(fd);
77 }
78
79 napi_value result = nullptr;
80 napi_create_int32(env, ret, &result);
81 return result;
82 }
83
Writev(napi_env env, napi_callback_info info)84 static napi_value Writev(napi_env env, napi_callback_info info)
85 {
86 size_t argc = 1;
87 napi_value args[1] = {nullptr};
88 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
89 int param;
90 napi_get_value_int32(env, args[0], ¶m);
91 ssize_t resultValue = FAILD;
92 if (param == PARAM_UNNORMAL) {
93 resultValue = writev(PARAM_UNNORMAL, nullptr, PARAM_UNNORMAL);
94 } else {
95 char str0[] = "test ";
96 char str1[] = "writev\n";
97 struct iovec iov[PARAM_2];
98
99 iov[PARAM_0].iov_base = str0;
100 iov[PARAM_0].iov_len = strlen(str0) + PARAM_1;
101 iov[PARAM_1].iov_base = str1;
102 iov[PARAM_1].iov_len = strlen(str1) + PARAM_1;
103
104 ssize_t result = writev(PARAM_1, iov, PARAM_2);
105 if (result == (iov[PARAM_0].iov_len + iov[PARAM_1].iov_len)) {
106 resultValue = RETURN_0;
107 }
108 }
109
110 napi_value result = nullptr;
111 napi_create_int32(env, resultValue, &result);
112
113 return result;
114 }
115
PReadV(napi_env env, napi_callback_info info)116 static napi_value PReadV(napi_env env, napi_callback_info info)
117 {
118 off_t offset = PARAM_0;
119 int ret;
120 int fd = open("/data/storage/el2/base/files/testReadv.txt", O_RDWR | O_CREAT, PARAM_0777);
121 char buf1[] = "testreadv1";
122 char buf2[] = "testreadv2";
123 struct iovec ios[] = {{buf1, strlen(buf1)}, {buf2, strlen(buf2)}};
124 ssize_t value = writev(fd, ios, sizeof(ios) / sizeof(struct iovec));
125 lseek(fd, PARAM_0, SEEK_SET);
126 memset(buf1, PARAM_0, sizeof(buf1));
127 memset(buf2, PARAM_0, sizeof(buf2));
128 value = preadv(fd, ios, sizeof(ios) / sizeof(struct iovec), offset);
129 if (value == strlen(buf1) + strlen(buf2)) {
130 ret = RETURN_0;
131 } else {
132 ret = FAIL;
133 }
134 close(fd);
135 napi_value result = nullptr;
136 napi_create_int32(env, ret, &result);
137 return result;
138 }
139
PReadV64(napi_env env, napi_callback_info info)140 static napi_value PReadV64(napi_env env, napi_callback_info info)
141 {
142 off_t offset = PARAM_0;
143 int ret;
144 int fd = open("/data/storage/el2/base/files/testReadv.txt", O_RDWR | O_CREAT, PARAM_0777);
145 char buf1[] = "testreadv1";
146 char buf2[] = "testreadv2";
147 struct iovec ios[] = {{buf1, strlen(buf1)}, {buf2, strlen(buf2)}};
148 ssize_t value = writev(fd, ios, sizeof(ios) / sizeof(struct iovec));
149 lseek(fd, PARAM_0, SEEK_SET);
150 memset(buf1, PARAM_0, sizeof(buf1));
151 memset(buf2, PARAM_0, sizeof(buf2));
152 value = preadv64(fd, ios, sizeof(ios) / sizeof(struct iovec), offset);
153 if (value == strlen(buf1) + strlen(buf2)) {
154 ret = RETURN_0;
155 } else {
156 ret = FAIL;
157 }
158 close(fd);
159 napi_value result = nullptr;
160 napi_create_int32(env, ret, &result);
161 return result;
162 }
163
PWriteV(napi_env env, napi_callback_info info)164 static napi_value PWriteV(napi_env env, napi_callback_info info)
165 {
166 char tmpfile[] = "/data/storage/el2/base/files/memfd_cr02100.txt";
167 char buf1[] = "preadv";
168 char buf2[] = "and pwritev";
169 struct iovec iov[2];
170
171 iov[0].iov_base = buf1;
172 iov[0].iov_len = sizeof(buf1) / sizeof(char);
173 iov[1].iov_base = buf2;
174 iov[1].iov_len = sizeof(buf2) / sizeof(char);
175
176 int fd = open(tmpfile, O_RDWR | O_CREAT, TEST_MODE);
177 int count = sizeof(iov) / sizeof(struct iovec);
178 int ret = pwritev(fd, iov, count, PARAM_0);
179 if (ret != PARAM_UNNORMAL) {
180 ret = SUCCESS;
181 } else {
182 ret = FAIL;
183 }
184 close(fd);
185 ret = access(tmpfile, F_OK);
186 if (ret == PARAM_0) {
187 ret = remove(tmpfile);
188 }
189 napi_value result = nullptr;
190 napi_create_int32(env, ret, &result);
191 return result;
192 }
PWriteV64(napi_env env, napi_callback_info info)193 static napi_value PWriteV64(napi_env env, napi_callback_info info)
194 {
195 char tmpfile[] = "/data/storage/el2/base/files/memfd_cr02100.txt";
196 char buf1[] = "preadv";
197 char buf2[] = "and pwritev";
198 struct iovec iov[2];
199
200 iov[0].iov_base = buf1;
201 iov[0].iov_len = sizeof(buf1) / sizeof(char);
202 iov[1].iov_base = buf2;
203 iov[1].iov_len = sizeof(buf2) / sizeof(char);
204
205 int fd = open(tmpfile, O_RDWR | O_CREAT, TEST_MODE);
206 int count = sizeof(iov) / sizeof(struct iovec);
207 int ret = pwritev64(fd, iov, count, PARAM_0);
208 if (ret != PARAM_UNNORMAL) {
209 ret = SUCCESS;
210 } else {
211 ret = FAIL;
212 }
213 close(fd);
214 ret = access(tmpfile, F_OK);
215 if (ret == PARAM_0) {
216 ret = remove(tmpfile);
217 }
218 napi_value result = nullptr;
219 napi_create_int32(env, ret, &result);
220 return result;
221 }
ProcessVmReadV(napi_env env, napi_callback_info info)222 static napi_value ProcessVmReadV(napi_env env, napi_callback_info info)
223 {
224 int ret = PARAM_UNNORMAL;
225 int bufferSize = PARAM_256;
226 char src[256] = "This is process_vm_readv_0100.";
227 char dst[256] = "";
228 struct iovec remote, local;
229 remote.iov_base = src;
230 remote.iov_len = bufferSize;
231
232 local.iov_base = dst;
233 local.iov_len = bufferSize;
234
235 int rev = process_vm_readv(getpid(), &local, PARAM_1, &remote, PARAM_1, PARAM_0);
236 if (rev == sizeof(src)) {
237 ret = RETURN_0;
238 } else {
239 ret = FAIL;
240 }
241 napi_value result = nullptr;
242 napi_create_int32(env, ret, &result);
243 return result;
244 }
ProcessVmWriteV(napi_env env, napi_callback_info info)245 static napi_value ProcessVmWriteV(napi_env env, napi_callback_info info)
246 {
247 int ret = PARAM_UNNORMAL;
248 char src[256] = "This is process_vm_readv_0100.";
249 char dst[256] = "";
250 struct iovec local = {.iov_base = src, .iov_len = sizeof(src)};
251 struct iovec remote = {.iov_base = dst, .iov_len = sizeof(dst)};
252
253 ssize_t rev = process_vm_writev(getpid(), &local, PARAM_1, &remote, PARAM_1, PARAM_0);
254 if (rev == sizeof(src)) {
255 ret = RETURN_0;
256 } else {
257 ret = FAIL;
258 }
259 napi_value result = nullptr;
260 napi_create_int32(env, ret, &result);
261 return result;
262 }
263 EXTERN_C_START
Init(napi_env env, napi_value exports)264 static napi_value Init(napi_env env, napi_value exports)
265 {
266 napi_property_descriptor desc[] = {
267 {"readv", nullptr, Readv, nullptr, nullptr, nullptr, napi_default, nullptr},
268 {"writev", nullptr, Writev, nullptr, nullptr, nullptr, napi_default, nullptr},
269 {"processVmReadV", nullptr, ProcessVmReadV, nullptr, nullptr, nullptr, napi_default, nullptr},
270 {"processVmWriteV", nullptr, ProcessVmWriteV, nullptr, nullptr, nullptr, napi_default, nullptr},
271 {"pReadV", nullptr, PReadV, nullptr, nullptr, nullptr, napi_default, nullptr},
272 {"pReadV64", nullptr, PReadV64, nullptr, nullptr, nullptr, napi_default, nullptr},
273 {"pWriteV", nullptr, PWriteV, nullptr, nullptr, nullptr, napi_default, nullptr},
274 {"pWriteV64", nullptr, PWriteV64, nullptr, nullptr, nullptr, napi_default, nullptr},
275
276 };
277 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
278 return exports;
279 }
280 EXTERN_C_END
281
282 static napi_module demoModule = {
283 .nm_version = 1,
284 .nm_flags = 0,
285 .nm_filename = nullptr,
286 .nm_register_func = Init,
287 .nm_modname = "uio",
288 .nm_priv = ((void *)0),
289 .reserved = {0},
290 };
291
RegisterModule(void)292 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
293