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