1 /*
2 * Copyright (c) 2023 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 <cerrno>
18 #include <cstdio>
19 #include <cstring>
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <js_native_api_types.h>
23 #include <malloc.h>
24 #include <unistd.h>
25
26 #define SUCCESS 1
27 #define STRLENGTH 64
28 #define DEFAULT_VALUE 0
29 #define FAIL (-1)
30 #define ONE 1
31 #define TWO 2
32 #define THREE 3
33 #define BUFF_SIZE (20)
34 #define FILEFLAG (0640)
35 #define PARAM_0 0
36 #define PARAM_1 1
37 #define PARAM_2 2
38 #define PARAM_0777 0777
39 #define PARAM_UNNORMAL (-1)
40 #define RETURN_0 0
41 #define FAILD (-1)
42 #define ERRON_0 0
43 #define SIZE_6 6
44 #define SIZE_8 8
45 #define SIZE_10 10
46 #define SIZE_100 100
47 #define SIZE_123 123
48 #define SIZE_256 256
49 #define SIZE_1024 1024
50 #define SIZE_4096 4096
51 #define SIZE_8192 8192
52 #define SIZE_32768 32768
53
Tee(napi_env env, napi_callback_info info)54 static napi_value Tee(napi_env env, napi_callback_info info)
55 {
56 size_t argc = PARAM_1;
57 napi_value args[1] = {nullptr};
58 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
59 int param;
60 napi_get_value_int32(env, args[0], ¶m);
61
62 int ret;
63 errno = ERRON_0;
64 if (param == PARAM_0) {
65 char buf[BUFF_SIZE];
66 char text[] = "Hello";
67 memset(buf, PARAM_0, sizeof(buf));
68 int pipefd1[PARAM_2];
69 pipe(pipefd1);
70 write(pipefd1[PARAM_1], text, strlen(text));
71 int pipefd2[PARAM_2];
72 pipe(pipefd2);
73 ret = tee(pipefd1[PARAM_0], pipefd2[PARAM_1], SIZE_32768, SPLICE_F_NONBLOCK);
74 close(pipefd1[PARAM_0]);
75 close(pipefd1[PARAM_1]);
76 close(pipefd2[PARAM_0]);
77 close(pipefd2[PARAM_1]);
78 } else {
79 ret = tee(PARAM_UNNORMAL, PARAM_UNNORMAL, SIZE_32768, SPLICE_F_NONBLOCK);
80 }
81 if (ret > PARAM_0) {
82 ret = PARAM_0;
83 }
84
85 napi_value result = nullptr;
86 napi_create_int32(env, ret, &result);
87 return result;
88 }
89
Vmsplice(napi_env env, napi_callback_info info)90 static napi_value Vmsplice(napi_env env, napi_callback_info info)
91 {
92 size_t argc = PARAM_1;
93 napi_value args[1] = {nullptr};
94 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
95 int param;
96 napi_get_value_int32(env, args[0], ¶m);
97
98 int pipe_size = PARAM_2;
99 int iov_length = SIZE_6;
100 int pipe_fds[pipe_size];
101 pipe(pipe_fds);
102 struct iovec v[pipe_size];
103 char strHello[] = "hello ";
104 char str_world[] = "world\n";
105 v[0].iov_base = strHello;
106 v[0].iov_len = iov_length;
107 v[1].iov_base = str_world;
108 v[1].iov_len = iov_length;
109 size_t result;
110 errno = ERRON_0;
111 if (param == PARAM_0) {
112 result = vmsplice(pipe_fds[PARAM_1], v, sizeof(v) / sizeof(struct iovec), PARAM_0);
113 } else {
114 result = vmsplice(pipe_fds[PARAM_1], v, PARAM_0, PARAM_0);
115 }
116 close(pipe_fds[1]);
117 if (result > PARAM_0) {
118 result = PARAM_0;
119 } else {
120 result = PARAM_UNNORMAL;
121 }
122
123 napi_value resultS = nullptr;
124 napi_create_int32(env, result, &resultS);
125 return resultS;
126 }
127
Readahead(napi_env env, napi_callback_info info)128 static napi_value Readahead(napi_env env, napi_callback_info info)
129 {
130 char path[] = "/data/storage/el2/base/files/testreadahead.txt";
131 char text[] = "test readahead";
132 size_t argc = PARAM_1;
133 napi_value args[1] = {nullptr};
134 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
135 int param;
136 napi_get_value_int32(env, args[0], ¶m);
137
138 int ret;
139 if (param == PARAM_0) {
140 int fd = open(path, O_CREAT | O_RDWR, PARAM_0777);
141 write(fd, text, strlen(text));
142 ret = readahead(fd, PARAM_0, strlen(text));
143 close(fd);
144 remove(path);
145 } else {
146 ret = readahead(PARAM_UNNORMAL, PARAM_0, SIZE_123);
147 }
148
149 napi_value result = nullptr;
150 napi_create_int32(env, ret, &result);
151 return result;
152 }
153
PosixFallocate(napi_env env, napi_callback_info info)154 static napi_value PosixFallocate(napi_env env, napi_callback_info info)
155 {
156 char path[] = "/data/storage/el2/base/files/test.txt";
157 size_t argc = PARAM_1;
158 napi_value args[1] = {nullptr};
159 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
160 int param;
161 napi_get_value_int32(env, args[0], ¶m);
162
163 int ret;
164 if (param == PARAM_0) {
165 int fd = open(path, O_CREAT | O_RDWR, PARAM_0777);
166 ret = posix_fallocate(fd, SIZE_8, SIZE_1024);
167 close(fd);
168 remove(path);
169 } else {
170 ret = posix_fallocate(PARAM_UNNORMAL, SIZE_8, SIZE_1024);
171 if (ret != PARAM_0) {
172 ret = PARAM_UNNORMAL;
173 }
174 }
175
176 napi_value result = nullptr;
177 napi_create_int32(env, ret, &result);
178 return result;
179 }
180
NameToHandleAt(napi_env env, napi_callback_info info)181 static napi_value NameToHandleAt(napi_env env, napi_callback_info info)
182 {
183 char dir[] = "/data/storage/el2/base/files/";
184 size_t argc = PARAM_1;
185 napi_value args[1] = {nullptr};
186 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
187 int param;
188 napi_get_value_int32(env, args[0], ¶m);
189
190 struct file_handle tempHandle;
191 tempHandle.handle_bytes = PARAM_0;
192 int mountId = 0;
193 int fd = 0;
194 DIR *dirfp = opendir(dir);
195 fd = dirfd(dirfp);
196
197 name_to_handle_at(fd, dir, &tempHandle, &mountId, PARAM_0);
198 struct file_handle *handle = (struct file_handle *)malloc(tempHandle.handle_bytes);
199 handle->handle_bytes = tempHandle.handle_bytes;
200
201 int ret = PARAM_0;
202 ret = name_to_handle_at(fd, dir, handle, &mountId, PARAM_0);
203
204 closedir(dirfp);
205 free(handle);
206
207 napi_value result = nullptr;
208 napi_create_int32(env, ret, &result);
209 return result;
210 }
211
Open(napi_env env, napi_callback_info info)212 static napi_value Open(napi_env env, napi_callback_info info)
213 {
214 char path[] = "/data/storage/el2/base/files/testopen.txt";
215 size_t argc = PARAM_1;
216 napi_value args[1] = {nullptr};
217 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
218 int param;
219 napi_get_value_int32(env, args[0], ¶m);
220
221 int fd;
222 if (param == PARAM_0) {
223 fd = open(path, O_CREAT | O_RDWR, PARAM_0777);
224 } else {
225 fd = open("/", O_CREAT | O_RDWR, PARAM_0777);
226 }
227 int ret;
228 if (fd != FAILD) {
229 close(fd);
230 remove(path);
231 ret = PARAM_0;
232 } else {
233 ret = PARAM_UNNORMAL;
234 }
235
236 napi_value result = nullptr;
237 napi_create_int32(env, ret, &result);
238 return result;
239 }
240
Open64(napi_env env, napi_callback_info info)241 static napi_value Open64(napi_env env, napi_callback_info info)
242 {
243 char path[] = "/data/storage/el2/base/files/testopen64.txt";
244 size_t argc = PARAM_1;
245 napi_value args[1] = {nullptr};
246 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
247 int param;
248 napi_get_value_int32(env, args[0], ¶m);
249
250 int fd;
251 if (param == PARAM_0) {
252 fd = open64(path, O_CREAT | O_RDWR, PARAM_0777);
253 } else {
254 fd = open64("/", O_CREAT | O_RDWR, PARAM_0777);
255 }
256 int ret;
257 if (fd != FAILD) {
258 close(fd);
259 remove(path);
260 ret = PARAM_0;
261 } else {
262 ret = PARAM_UNNORMAL;
263 }
264
265 napi_value result = nullptr;
266 napi_create_int32(env, ret, &result);
267 return result;
268 }
269
OpenByHandleAt(napi_env env, napi_callback_info info)270 static napi_value OpenByHandleAt(napi_env env, napi_callback_info info)
271 {
272 char dir[] = "/data/storage/el2/base/files/";
273 size_t argc = PARAM_1;
274 napi_value args[1] = {nullptr};
275 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
276 int param;
277 napi_get_value_int32(env, args[0], ¶m);
278
279 struct file_handle tempHandle;
280 tempHandle.handle_bytes = PARAM_0;
281 int mountId = 0;
282 int fd = 0;
283 DIR *dirfp = opendir(dir);
284 fd = dirfd(dirfp);
285
286 name_to_handle_at(fd, dir, &tempHandle, &mountId, PARAM_0);
287 struct file_handle *handle = (struct file_handle *)malloc(tempHandle.handle_bytes);
288 handle->handle_bytes = tempHandle.handle_bytes;
289
290 int ret = PARAM_0;
291 ret = name_to_handle_at(fd, dir, handle, &mountId, PARAM_0);
292 ret = open_by_handle_at(mountId, handle, PARAM_0);
293
294 closedir(dirfp);
295 free(handle);
296
297 napi_value result = nullptr;
298 napi_create_int32(env, ret, &result);
299 return result;
300 }
301
PosixFadvise(napi_env env, napi_callback_info info)302 static napi_value PosixFadvise(napi_env env, napi_callback_info info)
303 {
304 char path[] = "/data/storage/el2/base/files/test.txt";
305 size_t argc = PARAM_1;
306 napi_value args[1] = {nullptr};
307 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
308 int param;
309 napi_get_value_int32(env, args[0], ¶m);
310
311 int ret;
312 if (param == PARAM_0) {
313 int fd = open(path, O_CREAT | O_RDWR, PARAM_0777);
314 ret = posix_fadvise(fd, SIZE_8, SIZE_1024, POSIX_FADV_NORMAL);
315 close(fd);
316 remove(path);
317 } else {
318 ret = posix_fadvise(PARAM_UNNORMAL, SIZE_8, SIZE_1024, POSIX_FADV_NORMAL);
319 }
320 if (ret != PARAM_0) {
321 ret = PARAM_UNNORMAL;
322 }
323
324 napi_value result = nullptr;
325 napi_create_int32(env, ret, &result);
326 return result;
327 }
328
FalLocate(napi_env env, napi_callback_info info)329 static napi_value FalLocate(napi_env env, napi_callback_info info)
330 {
331 char path[] = "/data/storage/el2/base/files/testfallocate.txt";
332 char text[] = "test fallocate";
333 size_t argc = PARAM_1;
334 napi_value args[1] = {nullptr};
335 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
336 int param;
337 napi_get_value_int32(env, args[0], ¶m);
338
339 int ret;
340 if (param == PARAM_0) {
341 int fd = open(path, O_CREAT | O_RDWR, PARAM_0777);
342 write(fd, text, sizeof(text));
343 ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, SIZE_4096, SIZE_4096 * THREE);
344 close(fd);
345 remove(path);
346 } else {
347 ret = fallocate(PARAM_UNNORMAL, PARAM_0, PARAM_0, PARAM_0);
348 }
349
350 napi_value result = nullptr;
351 napi_create_int32(env, ret, &result);
352 return result;
353 }
354
FalLocate64(napi_env env, napi_callback_info info)355 static napi_value FalLocate64(napi_env env, napi_callback_info info)
356 {
357 char path[] = "/data/storage/el2/base/files/test.txt";
358 size_t argc = PARAM_1;
359 napi_value args[1] = {nullptr};
360 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
361 int param;
362 napi_get_value_int32(env, args[0], ¶m);
363
364 int ret;
365 if (param == PARAM_0) {
366 int fd = open(path, O_CREAT | O_RDWR, PARAM_0777);
367 ret = fallocate64(fd, FALLOC_FL_KEEP_SIZE, SIZE_4096, SIZE_4096 * THREE);
368 close(fd);
369 remove(path);
370 } else {
371 ret = fallocate64(PARAM_UNNORMAL, PARAM_0, PARAM_0, PARAM_0);
372 }
373
374 napi_value result = nullptr;
375 napi_create_int32(env, ret, &result);
376 return result;
377 }
378
FcnTl(napi_env env, napi_callback_info info)379 static napi_value FcnTl(napi_env env, napi_callback_info info)
380 {
381 char path[] = "/data/storage/el2/base/files/test.txt";
382 size_t argc = PARAM_1;
383 napi_value args[1] = {nullptr};
384 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
385 int param;
386 napi_get_value_int32(env, args[0], ¶m);
387
388 int ret;
389 if (param == PARAM_0) {
390 int fd = open(path, O_CREAT, PARAM_0777);
391 ret = fcntl(fd, F_GETFL);
392 if (ret != FAILD) {
393 ret = PARAM_0;
394 } else {
395 ret = PARAM_UNNORMAL;
396 }
397 close(fd);
398 remove(path);
399 } else {
400 ret = fcntl(PARAM_UNNORMAL, F_GETFL);
401 }
402
403 napi_value result = nullptr;
404 napi_create_int32(env, ret, &result);
405 return result;
406 }
407
408 extern "C" size_t __fwrite_chk(const void *buf, size_t size, size_t count, FILE *stream, size_t buf_size);
FwriteChk(napi_env env, napi_callback_info info)409 static napi_value FwriteChk(napi_env env, napi_callback_info info)
410 {
411 const char *TEMP_FILE = "/data/storage/el2/base/files/test.txt";
412 const char *gTempFileContent = "This is a test";
413 int len = strlen(gTempFileContent);
414 int ret = FAILD;
415 size_t writeCount = PARAM_0;
416 FILE *fp = nullptr;
417 do {
418 int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
419 fp = fdopen(fileDescribe, "w");
420 if (fp == nullptr) {
421 break;
422 }
423 writeCount = __fwrite_chk(gTempFileContent, len, 1, fp, len);
424 ret = writeCount == PARAM_1;
425 } while (PARAM_0);
426 if (fp != nullptr) {
427 fclose(fp);
428 }
429 remove(TEMP_FILE);
430 napi_value result = nullptr;
431 napi_create_int32(env, ret, &result);
432 return result;
433 }
434
435 EXTERN_C_START
Init(napi_env env, napi_value exports)436 static napi_value Init(napi_env env, napi_value exports)
437 {
438 napi_property_descriptor desc[] = {
439 {"nameToHandleAt", nullptr, NameToHandleAt, nullptr, nullptr, nullptr, napi_default, nullptr},
440 {"open", nullptr, Open, nullptr, nullptr, nullptr, napi_default, nullptr},
441 {"openByHandleAt", nullptr, OpenByHandleAt, nullptr, nullptr, nullptr, napi_default, nullptr},
442 {"open64", nullptr, Open64, nullptr, nullptr, nullptr, napi_default, nullptr},
443 {"tee", nullptr, Tee, nullptr, nullptr, nullptr, napi_default, nullptr},
444 {"vmsplice", nullptr, Vmsplice, nullptr, nullptr, nullptr, napi_default, nullptr},
445 {"readahead", nullptr, Readahead, nullptr, nullptr, nullptr, napi_default, nullptr},
446 {"posixfallocate", nullptr, PosixFallocate, nullptr, nullptr, nullptr, napi_default, nullptr},
447 {"posixfadvise", nullptr, PosixFadvise, nullptr, nullptr, nullptr, napi_default, nullptr},
448 {"fcntl", nullptr, FcnTl, nullptr, nullptr, nullptr, napi_default, nullptr},
449 {"fallocate64", nullptr, FalLocate64, nullptr, nullptr, nullptr, napi_default, nullptr},
450 {"fallocate", nullptr, FalLocate, nullptr, nullptr, nullptr, napi_default, nullptr},
451 {"fwritechk", nullptr, FwriteChk, nullptr, nullptr, nullptr, napi_default, nullptr},
452 };
453 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
454 return exports;
455 }
456 EXTERN_C_END
457
458 static napi_module demoModule = {
459 .nm_version = 1,
460 .nm_flags = 0,
461 .nm_filename = "fcntl1ndk",
462 .nm_register_func = Init,
463 .nm_modname = "libfcntl1ndk",
464 .nm_priv = ((void *)0),
465 .reserved = {0},
466 };
467
RegisterModule(void)468 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
469