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 <climits>
18 #include <csignal>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <dirent.h>
23 #include <fcntl.h>
24 #include <js_native_api.h>
25 #include <node_api.h>
26 #include <unistd.h>
27
28 #define FAIL (-1)
29 #define FALSE 0
30 #define ERROR (-1)
31 #define FIVE 5
32 #define ONE 1
33 #define PATH "/data/storage/el2/base/files"
34 #define FILE_PATH "/data/storage/el2/base/files/testdirent.txt"
35 #define ONEVAL 1
36 #define MINUSONE (-1)
37 #define TWOVAL 2
38 #define SIXFOURVAL 64
39 #define PARAM_0 0
40 #define PARAM_1 1
41 #define PARAM_2 2
42 #define PARAM_0777 0777
43 #define PARAM_UNNORMAL (-1)
44 #define RETURN_0 0
45 #define FAILD (-1)
46 #define ERRON_0 0
47 #define SIZE_10 10
48 #define SIZE_100 100
49 #define SIZE_4096 4096
50 #define SIZE_8192 8192
51 #define SIZE_0xFF 0xFF
52
53 #define INIT (-1)
54 #define SUCCESS_DIRENT 0
55
Telldir(napi_env env, napi_callback_info info)56 static napi_value Telldir(napi_env env, napi_callback_info info)
57 {
58 size_t argc = PARAM_1;
59 napi_value args[1] = {nullptr};
60 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
61 int param;
62 napi_get_value_int32(env, args[0], ¶m);
63
64 long ret;
65 if (param == PARAM_0) {
66 DIR *dir = opendir(PATH);
67 ret = telldir(dir);
68 closedir(dir);
69 } else {
70 DIR *dir = static_cast<DIR *>(malloc(SIZE_4096));
71 memset(dir, SIZE_0xFF, SIZE_4096);
72 ret = telldir(dir);
73 free(dir);
74 }
75
76 napi_value result;
77 napi_create_int32(env, ret, &result);
78 return result;
79 }
80
Readdir(napi_env env, napi_callback_info info)81 static napi_value Readdir(napi_env env, napi_callback_info info)
82 {
83 size_t argc = PARAM_1;
84 napi_value args[1] = {nullptr};
85 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
86 int param;
87 napi_get_value_int32(env, args[0], ¶m);
88
89 struct dirent *val;
90 if (param == PARAM_0) {
91 DIR *dir = opendir(PATH);
92 val = readdir(dir);
93 closedir(dir);
94 } else {
95 DIR *dir = static_cast<DIR *>(malloc(SIZE_4096));
96 memset(dir, SIZE_0xFF, SIZE_4096);
97 val = readdir(dir);
98 free(dir);
99 }
100 int ret;
101 if (val == nullptr) {
102 ret = FAILD;
103 } else {
104 ret = RETURN_0;
105 }
106
107 napi_value result = nullptr;
108 napi_create_int32(env, ret, &result);
109 return result;
110 }
111
ReaddirR(napi_env env, napi_callback_info info)112 static napi_value ReaddirR(napi_env env, napi_callback_info info)
113 {
114 size_t argc = PARAM_1;
115 napi_value args[1] = {nullptr};
116 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
117 int param;
118 napi_get_value_int32(env, args[0], ¶m);
119
120 int ret;
121 struct dirent buf;
122 struct dirent *res;
123 if (param == PARAM_0) {
124 DIR *dir = opendir(PATH);
125 ret = readdir_r(dir, &buf, &res);
126 closedir(dir);
127 } else {
128 DIR *dir = static_cast<DIR *>(malloc(SIZE_4096));
129 memset(dir, SIZE_0xFF, SIZE_4096);
130 ret = readdir_r(dir, &buf, &res);
131 free(dir);
132 if (ret != PARAM_0) {
133 ret = FAILD;
134 }
135 }
136
137 napi_value result = nullptr;
138 napi_create_int32(env, ret, &result);
139 return result;
140 }
141
Readdir64(napi_env env, napi_callback_info info)142 static napi_value Readdir64(napi_env env, napi_callback_info info)
143 {
144 size_t argc = PARAM_1;
145 napi_value args[1] = {nullptr};
146 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
147 int param;
148 napi_get_value_int32(env, args[0], ¶m);
149
150 struct dirent *val;
151 if (param == PARAM_0) {
152 DIR *dir = opendir(PATH);
153 val = readdir64(dir);
154 closedir(dir);
155 } else {
156 DIR *dir = static_cast<DIR *>(malloc(SIZE_4096));
157 memset(dir, SIZE_0xFF, SIZE_4096);
158 val = readdir64(dir);
159 free(dir);
160 }
161 int ret;
162 if (val == nullptr) {
163 ret = FAILD;
164 } else {
165 ret = RETURN_0;
166 }
167
168 napi_value result = nullptr;
169 napi_create_int32(env, ret, &result);
170 return result;
171 }
172
Readdir64R(napi_env env, napi_callback_info info)173 static napi_value Readdir64R(napi_env env, napi_callback_info info)
174 {
175 size_t argc = PARAM_1;
176 napi_value args[1] = {nullptr};
177 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
178 int param;
179 napi_get_value_int32(env, args[0], ¶m);
180
181 int ret;
182 struct dirent buf;
183 struct dirent *res;
184 if (param == PARAM_0) {
185 DIR *dir = opendir(PATH);
186 ret = readdir64_r(dir, &buf, &res);
187 closedir(dir);
188 } else {
189 DIR *dir = static_cast<DIR *>(malloc(SIZE_4096));
190 memset(dir, SIZE_0xFF, SIZE_4096);
191 ret = readdir64_r(dir, &buf, &res);
192 free(dir);
193 if (ret != PARAM_0) {
194 ret = FAILD;
195 }
196 }
197
198 napi_value result = nullptr;
199 napi_create_int32(env, ret, &result);
200 return result;
201 }
202
Rewinddir(napi_env env, napi_callback_info info)203 static napi_value Rewinddir(napi_env env, napi_callback_info info)
204 {
205 size_t argc = PARAM_1;
206 napi_value args[1] = {nullptr};
207 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
208 int param;
209 napi_get_value_int32(env, args[0], ¶m);
210
211 int ret;
212 if (param == PARAM_0) {
213 DIR *dir = opendir(PATH);
214 struct dirent *val = readdir(dir);
215 char *dName = val->d_name;
216 while ((val = readdir(dir)) != nullptr) {
217 break;
218 }
219 rewinddir(dir);
220 val = readdir(dir);
221 ret = strcmp(dName, val->d_name);
222 closedir(dir);
223 } else {
224 DIR *dir = static_cast<DIR *>(malloc(SIZE_4096));
225 memset(dir, SIZE_0xFF, SIZE_4096);
226 rewinddir(dir);
227 struct dirent *val = readdir(dir);
228 if (val == nullptr) {
229 ret = FAILD;
230 } else {
231 ret = RETURN_0;
232 }
233 free(dir);
234 }
235
236 napi_value result = nullptr;
237 napi_create_int32(env, ret, &result);
238 return result;
239 }
240
FdOpenDir(napi_env env, napi_callback_info info)241 static napi_value FdOpenDir(napi_env env, napi_callback_info info)
242 {
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 DIR *fdir;
250 if (param == PARAM_0) {
251 DIR *dir = opendir(PATH);
252 int fd = dirfd(dir);
253 fdir = fdopendir(fd);
254 close(fd);
255 closedir(dir);
256 } else {
257 fdir = fdopendir(PARAM_UNNORMAL);
258 }
259 int ret;
260 if (fdir == nullptr) {
261 ret = FAILD;
262 } else {
263 ret = RETURN_0;
264 closedir(fdir);
265 }
266
267 napi_value result = nullptr;
268 napi_create_int32(env, ret, &result);
269 return result;
270 }
271
CloseDir(napi_env env, napi_callback_info info)272 static napi_value CloseDir(napi_env env, napi_callback_info info)
273 {
274 size_t argc = PARAM_1;
275 napi_value args[1] = {nullptr};
276 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
277 int param;
278 napi_get_value_int32(env, args[0], ¶m);
279
280 int ret;
281 if (param == PARAM_0) {
282 DIR *dir = opendir(PATH);
283 ret = closedir(dir);
284 } else {
285 DIR *dir = static_cast<DIR *>(malloc(SIZE_4096));
286 memset(dir, SIZE_0xFF, SIZE_4096);
287 ret = closedir(dir);
288 }
289
290 napi_value result = nullptr;
291 napi_create_int32(env, ret, &result);
292 return result;
293 }
294
DirFd(napi_env env, napi_callback_info info)295 static napi_value DirFd(napi_env env, napi_callback_info info)
296 {
297 size_t argc = PARAM_1;
298 napi_value args[1] = {nullptr};
299 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
300 int param;
301 napi_get_value_int32(env, args[0], ¶m);
302
303 int ret;
304 if (param == PARAM_0) {
305 DIR *dir = opendir(PATH);
306 ret = dirfd(dir);
307 closedir(dir);
308 } else {
309 DIR *dir = static_cast<DIR *>(malloc(SIZE_4096));
310 memset(dir, SIZE_0xFF, SIZE_4096);
311 ret = dirfd(dir);
312 free(dir);
313 }
314 if (ret != PARAM_UNNORMAL) {
315 ret = RETURN_0;
316 }
317
318 napi_value result = nullptr;
319 napi_create_int32(env, ret, &result);
320 return result;
321 }
322
Alphasort(napi_env env, napi_callback_info info)323 static napi_value Alphasort(napi_env env, napi_callback_info info)
324 {
325 size_t argc = PARAM_1;
326 napi_value args[1] = {nullptr};
327 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
328 int param;
329 napi_get_value_int32(env, args[0], ¶m);
330
331 int total;
332 struct dirent **namelist;
333 if (param == PARAM_0) {
334 int fd = open(FILE_PATH, O_CREAT, PARAM_0777);
335 close(fd);
336 total = scandir(PATH, &namelist, PARAM_0, alphasort);
337 remove(FILE_PATH);
338 } else {
339 total = scandir(nullptr, &namelist, PARAM_0, alphasort);
340 }
341 int ret;
342 if (total > PARAM_0) {
343 ret = RETURN_0;
344 } else {
345 ret = FAILD;
346 }
347
348 napi_value result = nullptr;
349 napi_create_int32(env, ret, &result);
350 return result;
351 }
352
Alphasort64(napi_env env, napi_callback_info info)353 static napi_value Alphasort64(napi_env env, napi_callback_info info)
354 {
355 size_t argc = PARAM_1;
356 napi_value args[1] = {nullptr};
357 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
358 int param;
359 napi_get_value_int32(env, args[0], ¶m);
360
361 int total;
362 struct dirent **namelist;
363 if (param == PARAM_0) {
364 int fd = open(FILE_PATH, O_CREAT, PARAM_0777);
365 close(fd);
366 total = scandir(PATH, &namelist, PARAM_0, alphasort64);
367 remove(FILE_PATH);
368 } else {
369 total = scandir(nullptr, &namelist, PARAM_0, alphasort64);
370 }
371 int ret;
372 if (total > PARAM_0) {
373 ret = RETURN_0;
374 } else {
375 ret = FAILD;
376 }
377
378 napi_value result = nullptr;
379 napi_create_int32(env, ret, &result);
380 return result;
381 }
382
Getdents(napi_env env, napi_callback_info info)383 static napi_value Getdents(napi_env env, napi_callback_info info)
384 {
385 size_t argc = PARAM_1;
386 napi_value args[1] = {nullptr};
387 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
388 int param;
389 napi_get_value_int32(env, args[0], ¶m);
390
391 int ret;
392 struct dirent buf;
393 if (param == PARAM_0) {
394 DIR *dir = opendir(PATH);
395 int fd = dirfd(dir);
396 ret = getdents(fd, &buf, INT_MAX);
397 close(fd);
398 closedir(dir);
399 } else {
400 ret = getdents(PARAM_UNNORMAL, &buf, INT_MAX);
401 }
402 if (ret > PARAM_0) {
403 ret = PARAM_0;
404 }
405
406 napi_value result = nullptr;
407 napi_create_int32(env, ret, &result);
408 return result;
409 }
410
Getdents64(napi_env env, napi_callback_info info)411 static napi_value Getdents64(napi_env env, napi_callback_info info)
412 {
413 size_t argc = PARAM_1;
414 napi_value args[1] = {nullptr};
415 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
416 int param;
417 napi_get_value_int32(env, args[0], ¶m);
418
419 int ret;
420 struct dirent buf;
421 if (param == PARAM_0) {
422 DIR *dir = opendir(PATH);
423 int fd = dirfd(dir);
424 ret = getdents64(fd, &buf, INT_MAX);
425 close(fd);
426 closedir(dir);
427 } else {
428 ret = getdents64(PARAM_UNNORMAL, &buf, INT_MAX);
429 }
430 if (ret > PARAM_0) {
431 ret = PARAM_0;
432 }
433
434 napi_value result = nullptr;
435 napi_create_int32(env, ret, &result);
436 return result;
437 }
438
439 EXTERN_C_START
Init(napi_env env, napi_value exports)440 static napi_value Init(napi_env env, napi_value exports)
441 {
442 napi_property_descriptor desc[] = {
443 {"telldir", nullptr, Telldir, nullptr, nullptr, nullptr, napi_default, nullptr},
444 {"readdir", nullptr, Readdir, nullptr, nullptr, nullptr, napi_default, nullptr},
445 {"readdirR", nullptr, ReaddirR, nullptr, nullptr, nullptr, napi_default, nullptr},
446 {"readdir64", nullptr, Readdir64, nullptr, nullptr, nullptr, napi_default, nullptr},
447 {"readdir64R", nullptr, Readdir64R, nullptr, nullptr, nullptr, napi_default, nullptr},
448 {"rewinddir", nullptr, Rewinddir, nullptr, nullptr, nullptr, napi_default, nullptr},
449 {"fdopendir", nullptr, FdOpenDir, nullptr, nullptr, nullptr, napi_default, nullptr},
450 {"closedir", nullptr, CloseDir, nullptr, nullptr, nullptr, napi_default, nullptr},
451 {"dirfd", nullptr, DirFd, nullptr, nullptr, nullptr, napi_default, nullptr},
452 {"alphasort", nullptr, Alphasort, nullptr, nullptr, nullptr, napi_default, nullptr},
453 {"alphasort64", nullptr, Alphasort64, nullptr, nullptr, nullptr, napi_default, nullptr},
454 {"getdents", nullptr, Getdents, nullptr, nullptr, nullptr, napi_default, nullptr},
455 {"getdents64", nullptr, Getdents64, nullptr, nullptr, nullptr, napi_default, nullptr},
456 };
457 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
458 return exports;
459 }
460 EXTERN_C_END
461
462 static napi_module demoModule = {
463 .nm_version = 1,
464 .nm_flags = 0,
465 .nm_filename = nullptr,
466 .nm_register_func = Init,
467 .nm_modname = "dirent",
468 .nm_priv = ((void *)0),
469 .reserved = {0},
470 };
471
RegisterEntryModule(void)472 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
473