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 "common/napi_helper.cpp"
17 #include "napi/native_api.h"
18 #include <cstdio>
19 #include <cstring>
20 #include <fcntl.h>
21 #include <ifaddrs.h>
22 #include <js_native_api_types.h>
23 #include <linux/quota.h>
24 #include <net/if.h>
25 #include <string>
26 #include <sys/inotify.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <utmp.h>
30 #include <uv.h>
31 #include <hilog/log.h>
32
33 #define ONE 1
34 #define TWO 2
35 #define SIZE_2 2
36 #define PATH "/data/storage/el2/base/files"
37 #define PARAM_777 777
38 #define PARAM_0777 0777
39 #define PARAM_0 0
40 #define PARAM_1 1
41 #define PARAM_2 2
42 #define PARAM_UNNORMAL (-1)
43 #define ERRON_0 0
44 #define SUCCESS 1
45 #define SIZE_64 64
46 #define SEC_TIME 123840
47 #define TEST_MODE 0666
48 #define TEST_AT_FDCWD (-100)
49 #define TEST_ERROR_AT_FDCWD 100
50 #define NO_ERR 0
51 #define SUCCESS 1
52 #define FAIL (-1)
53 #define TEN 10
54 #define TEST_FIFO_MODE 0666
55 #define BUFSIZE 128
56 #define PARAM_3 3
57 #undef LOG_DOMAIN
58 #undef LOG_TAG
59 #define LOG_DOMAIN 0xFEFE
60 #define LOG_TAG "MUSL_STATNDK"
61
Stat(napi_env env, napi_callback_info info)62 static napi_value Stat(napi_env env, napi_callback_info info)
63 {
64 size_t argc = PARAM_1;
65 napi_value args[PARAM_1] = {nullptr};
66 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
67
68 int value;
69 napi_get_value_int32(env, args[PARAM_0], &value);
70 int intValue = PARAM_0;
71 struct stat sb = {PARAM_0};
72 if (value == ONE) {
73 intValue = stat(PATH, &sb);
74 } else if (value == TWO) {
75 intValue = stat(nullptr, &sb);
76 }
77 napi_value result = nullptr;
78 napi_create_int32(env, intValue, &result);
79 return result;
80 }
Stat64(napi_env env, napi_callback_info info)81 static napi_value Stat64(napi_env env, napi_callback_info info)
82 {
83 size_t argc = PARAM_1;
84 napi_value args[PARAM_1] = {nullptr};
85 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
86 int value;
87 napi_get_value_int32(env, args[PARAM_0], &value);
88 int intValue = PARAM_0;
89 struct stat64 sb = {PARAM_0};
90 if (value == ONE) {
91 intValue = stat64(PATH, &sb);
92 } else if (value == TWO) {
93 intValue = stat64(nullptr, &sb);
94 }
95 napi_value result = nullptr;
96 napi_create_int32(env, intValue, &result);
97 return result;
98 }
99
Umask(napi_env env, napi_callback_info info)100 static napi_value Umask(napi_env env, napi_callback_info info)
101 {
102 size_t argc = PARAM_1;
103 napi_value args[PARAM_1] = {nullptr};
104 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
105 int valueFirst;
106 napi_get_value_int32(env, args[PARAM_0], &valueFirst);
107 mode_t mode = PARAM_0;
108 if (valueFirst == PARAM_777) {
109 mode = S_IRWXU | S_IRWXG | S_IRWXO;
110 }
111 mode_t umaskValue = umask(mode);
112 umaskValue = umask(umaskValue);
113
114 int toJs = FAIL;
115 if (umaskValue == mode && valueFirst == PARAM_777) {
116 toJs = SUCCESS;
117 }
118 napi_value result = nullptr;
119 napi_create_int32(env, toJs, &result);
120 return result;
121 }
122
Utimensat(napi_env env, napi_callback_info info)123 static napi_value Utimensat(napi_env env, napi_callback_info info)
124 {
125 int toCppResult = FAIL;
126 char path[] = "/data/storage/el2/base/files/Utimensat.txt";
127 int fd = open(path, O_CREAT);
128
129 struct timespec times[] = {{.tv_nsec = UTIME_OMIT}, {.tv_nsec = UTIME_OMIT}};
130
131 int utimensatValue = utimensat(fd, path, times, PARAM_0);
132 if (utimensatValue == PARAM_0) {
133 toCppResult = SUCCESS;
134 }
135 close(fd);
136 remove(path);
137 napi_value result = nullptr;
138 napi_create_int32(env, toCppResult, &result);
139 return result;
140 }
141
FchModAt(napi_env env, napi_callback_info info)142 static napi_value FchModAt(napi_env env, napi_callback_info info)
143 {
144 char path[] = "/data/storage/el2/base/files/modAt.txt";
145 int df = open(path, O_CREAT, PARAM_0777);
146 int ret = fchmodat(df, path, S_IRUSR, PARAM_0);
147 close(df);
148 remove(path);
149 napi_value result = nullptr;
150 napi_create_int32(env, ret, &result);
151 return result;
152 }
153
FchMod(napi_env env, napi_callback_info info)154 static napi_value FchMod(napi_env env, napi_callback_info info)
155 {
156 char path[] = "/data/storage/el2/base/files/mod.txt";
157 int df = open(path, O_CREAT, PARAM_0777);
158 int ret = fchmod(df, S_IRUSR);
159 close(df);
160 remove(path);
161 napi_value result = nullptr;
162 napi_create_int32(env, ret, &result);
163 return result;
164 }
165
Creat(napi_env env, napi_callback_info info)166 static napi_value Creat(napi_env env, napi_callback_info info)
167 {
168 int backResult;
169 char path[] = "/data/storage/el2/base/files/Fzl.txt";
170 backResult = creat(path, O_CREAT);
171 napi_value result = nullptr;
172 if (backResult != FAIL) {
173 napi_create_int32(env, PARAM_0, &result);
174 } else {
175 napi_create_int32(env, PARAM_UNNORMAL, &result);
176 }
177 remove(path);
178 return result;
179 }
180
Creat64(napi_env env, napi_callback_info info)181 static napi_value Creat64(napi_env env, napi_callback_info info)
182 {
183 int backResult;
184 char path[] = "/data/storage/el2/base/files/Fzl.txt";
185 backResult = creat64(path, O_CREAT);
186 napi_value result = nullptr;
187 if (backResult != FAIL) {
188 napi_create_int32(env, PARAM_0, &result);
189 } else {
190 napi_create_int32(env, PARAM_UNNORMAL, &result);
191 }
192 remove(path);
193 return result;
194 }
195
Chmod(napi_env env, napi_callback_info info)196 static napi_value Chmod(napi_env env, napi_callback_info info)
197 {
198 int returnValue = chmod("/data/storage/el2/base/files", S_IRWXU | S_IRWXG | S_IRWXO);
199 napi_value result;
200 napi_create_int32(env, returnValue, &result);
201 return result;
202 }
203
Fstat(napi_env env, napi_callback_info info)204 static napi_value Fstat(napi_env env, napi_callback_info info)
205 {
206 size_t argc = PARAM_1;
207 napi_value args[PARAM_1] = {nullptr};
208 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
209 size_t length = SIZE_64;
210 size_t stresult = PARAM_0;
211 char path[SIZE_64] = {PARAM_0};
212 napi_get_value_string_utf8(env, args[PARAM_0], path, length, &stresult);
213 struct stat sb = {PARAM_0};
214 int fd = open(path, O_CREAT, PARAM_0777);
215 int value = fstat(fd, &sb);
216 napi_value result;
217 napi_create_int32(env, value, &result);
218 close(fd);
219 return result;
220 }
221
Fstat64(napi_env env, napi_callback_info info)222 static napi_value Fstat64(napi_env env, napi_callback_info info)
223 {
224 size_t argc = PARAM_1;
225 napi_value args[PARAM_1] = {nullptr};
226 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
227 size_t length = SIZE_64;
228 size_t stresult = PARAM_0;
229 char path[SIZE_64] = {PARAM_0};
230 napi_get_value_string_utf8(env, args[PARAM_0], path, length, &stresult);
231 struct stat sb = {PARAM_0};
232 int fd = open(path, O_CREAT, PARAM_0777);
233 int value = fstat64(fd, &sb);
234 napi_value result;
235 napi_create_int32(env, value, &result);
236 close(fd);
237 return result;
238 }
239
Fstatat(napi_env env, napi_callback_info info)240 static napi_value Fstatat(napi_env env, napi_callback_info info)
241 {
242 size_t argc = PARAM_1;
243 napi_value args[PARAM_1] = {nullptr};
244 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
245 size_t length = SIZE_64;
246 size_t stresult = PARAM_0;
247 char path[SIZE_64] = {PARAM_0};
248 napi_get_value_string_utf8(env, args[PARAM_0], path, length, &stresult);
249 struct stat st = {PARAM_0};
250 int fd = open(path, O_CREAT, PARAM_0777);
251 int ret = fstatat(AT_FDCWD, path, &st, PARAM_0);
252 napi_value result;
253 napi_create_int32(env, ret, &result);
254 close(fd);
255 return result;
256 }
257
Fstatat64(napi_env env, napi_callback_info info)258 static napi_value Fstatat64(napi_env env, napi_callback_info info)
259 {
260 size_t argc = PARAM_1;
261 napi_value args[PARAM_1] = {nullptr};
262 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
263 size_t length = SIZE_64;
264 size_t stresult = PARAM_0;
265 char path[SIZE_64] = {PARAM_0};
266 napi_get_value_string_utf8(env, args[PARAM_0], path, length, &stresult);
267 struct stat st = {PARAM_0};
268 int fd = open(path, O_CREAT, PARAM_0777);
269 int ret = fstatat64(AT_FDCWD, path, &st, PARAM_0);
270 napi_value result;
271 napi_create_int32(env, ret, &result);
272 close(fd);
273 return result;
274 }
275
Futimens(napi_env env, napi_callback_info info)276 static napi_value Futimens(napi_env env, napi_callback_info info)
277 {
278 int fd = open("/data/storage/el2/base/files/utime.txt", O_CREAT, PARAM_0777);
279 int ret = futimens(fd, ((struct timespec[PARAM_2]){{.tv_nsec = UTIME_OMIT}, {.tv_nsec = UTIME_OMIT}}));
280 napi_value result;
281 napi_create_int32(env, ret, &result);
282 close(fd);
283 remove("/data/storage/el2/base/files/utime.txt");
284 return result;
285 }
MkFifoAt(napi_env env, napi_callback_info info)286 static napi_value MkFifoAt(napi_env env, napi_callback_info info)
287 {
288 napi_value result = nullptr;
289 size_t argc = PARAM_2;
290 napi_value args[PARAM_2] = {nullptr};
291 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
292 int ret, name;
293 napi_get_value_int32(env, args[PARAM_0], &name);
294 size_t length = SIZE_64;
295 size_t strResult = PARAM_0;
296 char path[length];
297 napi_get_value_string_utf8(env, args[PARAM_1], path, length, &strResult);
298 errno = 0;
299 ret = mkfifoat(name, path, S_IFIFO | TEST_FIFO_MODE);
300 if (ret != 0) {
301 OH_LOG_INFO(LOG_APP, "MUSL mkfifoat ret %{public}d errno : %{public}d", ret, errno);
302 if (ret == -1 && errno == EACCES) {
303 ret = 0;
304 }
305 }
306 unlink(path);
307 remove(path);
308 napi_create_int32(env, ret, &result);
309 return result;
310 }
311
MkNodAt(napi_env env, napi_callback_info info)312 static napi_value MkNodAt(napi_env env, napi_callback_info info)
313 {
314 size_t argc = PARAM_3;
315 napi_value args[PARAM_3] = {nullptr};
316 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
317 int ret = 0;
318 int dirfd = 0;
319 int mode = 0;
320 napi_get_value_int32(env, args[PARAM_0], &dirfd);
321 size_t length = SIZE_64;
322 size_t strResult = PARAM_0;
323 char path[length];
324 napi_get_value_string_utf8(env, args[PARAM_1], path, length, &strResult);
325 napi_get_value_int32(env, args[PARAM_2], &mode);
326 dev_t st_dev = PARAM_0;
327 errno = 0;
328 ret = mknodat(dirfd, path, mode, st_dev);
329 int mkret = ret;
330 int mkerrno = errno;
331 if (ret != 0) {
332 OH_LOG_INFO(LOG_APP, "MUSL mknodat ret %{public}d errno : %{public}d", ret, errno);
333 if (ret == -1 && (errno == EACCES || errno == EPERM)) {
334 ret = 0;
335 }
336 }
337 struct stat newFifo = {PARAM_0};
338 errno = 0;
339 if (mkret == 0 || mkerrno == EEXIST) {
340 ret = stat(path, &newFifo);
341 if (ret != 0) {
342 OH_LOG_INFO(LOG_APP, "MUSL stat ret %{public}d errno : %{public}d", ret, errno);
343 }
344 }
345 napi_value result;
346 napi_create_int32(env, ret, &result);
347 unlink(path);
348 return result;
349 }
350
MkNod(napi_env env, napi_callback_info info)351 static napi_value MkNod(napi_env env, napi_callback_info info)
352 {
353 size_t argc = PARAM_2;
354 napi_value args[PARAM_2] = {nullptr};
355 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
356 size_t length = SIZE_64;
357 size_t strResult = PARAM_0;
358 char pathname[PATH_MAX];
359 napi_get_value_string_utf8(env, args[PARAM_0], pathname, length, &strResult);
360 int mode = PARAM_0;
361 napi_get_value_int32(env, args[PARAM_1], &mode);
362 int ret = PARAM_0;
363 napi_value result;
364 napi_create_int32(env, ret, &result);
365 return result;
366 }
367
MkDir(napi_env env, napi_callback_info info)368 static napi_value MkDir(napi_env env, napi_callback_info info)
369 {
370 int ret = PARAM_0;
371 char path[] = "/data/storage/el2/base/files/mkdir1";
372 if (access(path, F_OK) != PARAM_0) {
373 ret = mkdir(path, S_IRWXG);
374 remove(path);
375 } else {
376 remove(path);
377 ret = mkdir(path, S_IRWXG);
378 remove(path);
379 }
380 napi_value result = nullptr;
381 napi_create_int32(env, ret, &result);
382 return result;
383 }
384
MkDirAt(napi_env env, napi_callback_info info)385 static napi_value MkDirAt(napi_env env, napi_callback_info info)
386 {
387 int ret = PARAM_0;
388 char path[] = "/data/storage/el2/base/files/mkdirat1";
389 ret = mkdirat(PARAM_0, path, S_IRWXG);
390 napi_value result = nullptr;
391 napi_create_int32(env, ret, &result);
392 return result;
393 }
394
MkFiFo(napi_env env, napi_callback_info info)395 static napi_value MkFiFo(napi_env env, napi_callback_info info)
396 {
397 size_t argc = PARAM_1;
398 napi_value args[PARAM_1] = {nullptr};
399 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
400 size_t lenA;
401 size_t lenV = BUFSIZE;
402 char path[BUFSIZE] = {PARAM_0};
403 napi_get_value_string_utf8(env, args[PARAM_0], path, lenV, &lenA);
404 int ret = PARAM_0;
405 unlink(path);
406 remove(path);
407 napi_value result = nullptr;
408 napi_create_int32(env, ret, &result);
409 return result;
410 }
411
Lstat(napi_env env, napi_callback_info info)412 static napi_value Lstat(napi_env env, napi_callback_info info)
413 {
414 struct stat statbuff;
415 int32_t ret = lstat("/etc/passwd", &statbuff);
416 napi_value result = nullptr;
417 if (ret == FAIL) {
418 napi_create_int32(env, PARAM_UNNORMAL, &result);
419 } else {
420 napi_create_int32(env, PARAM_0, &result);
421 }
422 return result;
423 }
424
Lstat64(napi_env env, napi_callback_info info)425 static napi_value Lstat64(napi_env env, napi_callback_info info)
426 {
427 struct stat statbuff;
428 int32_t ret = lstat64("/etc/passwd", &statbuff);
429 napi_value result = nullptr;
430 if (ret == FAIL) {
431 napi_create_int32(env, PARAM_UNNORMAL, &result);
432 } else {
433 napi_create_int32(env, PARAM_0, &result);
434 }
435 return result;
436 }
437
438 EXTERN_C_START
Init(napi_env env, napi_value exports)439 static napi_value Init(napi_env env, napi_value exports)
440 {
441 napi_property_descriptor desc[] = {
442 {"stat", nullptr, Stat, nullptr, nullptr, nullptr, napi_default, nullptr},
443 {"stat64", nullptr, Stat64, nullptr, nullptr, nullptr, napi_default, nullptr},
444 {"umask", nullptr, Umask, nullptr, nullptr, nullptr, napi_default, nullptr},
445 {"utimensat", nullptr, Utimensat, nullptr, nullptr, nullptr, napi_default, nullptr},
446 {"fchmodat", nullptr, FchModAt, nullptr, nullptr, nullptr, napi_default, nullptr},
447 {"fchmod", nullptr, FchMod, nullptr, nullptr, nullptr, napi_default, nullptr},
448 {"creat", nullptr, Creat, nullptr, nullptr, nullptr, napi_default, nullptr},
449 {"creat64", nullptr, Creat64, nullptr, nullptr, nullptr, napi_default, nullptr},
450 {"chmod", nullptr, Chmod, nullptr, nullptr, nullptr, napi_default, nullptr},
451 {"fstat", nullptr, Fstat, nullptr, nullptr, nullptr, napi_default, nullptr},
452 {"fstat64", nullptr, Fstat64, nullptr, nullptr, nullptr, napi_default, nullptr},
453 {"fstatat", nullptr, Fstatat, nullptr, nullptr, nullptr, napi_default, nullptr},
454 {"fstatat64", nullptr, Fstatat64, nullptr, nullptr, nullptr, napi_default, nullptr},
455 {"futimens", nullptr, Futimens, nullptr, nullptr, nullptr, napi_default, nullptr},
456 {"mkFifoAt", nullptr, MkFifoAt, nullptr, nullptr, nullptr, napi_default, nullptr},
457 {"mkNodAt", nullptr, MkNodAt, nullptr, nullptr, nullptr, napi_default, nullptr},
458 {"mkNod", nullptr, MkNod, nullptr, nullptr, nullptr, napi_default, nullptr},
459 {"mkDir", nullptr, MkDir, nullptr, nullptr, nullptr, napi_default, nullptr},
460 {"mkDirAt", nullptr, MkDirAt, nullptr, nullptr, nullptr, napi_default, nullptr},
461 {"lstat", nullptr, Lstat, nullptr, nullptr, nullptr, napi_default, nullptr},
462 {"lstat64", nullptr, Lstat64, nullptr, nullptr, nullptr, napi_default, nullptr},
463 {"mkFiFo", nullptr, MkFiFo, nullptr, nullptr, nullptr, napi_default, nullptr},
464
465 };
466 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
467 return exports;
468 }
469 EXTERN_C_END
470
471 static napi_module demoModule = {
472 .nm_version = 1,
473 .nm_flags = 0,
474 .nm_filename = nullptr,
475 .nm_register_func = Init,
476 .nm_modname = "stat",
477 .nm_priv = ((void *)0),
478 .reserved = {0},
479 };
480
RegisterModule(void)481 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
482