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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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], &param);
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