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 <cstring>
17 #include <fcntl.h>
18 #include <js_native_api.h>
19 #include <js_native_api_types.h>
20 #include <node_api.h>
21 #include <stdio_ext.h>
22 #include <unistd.h>
23 
24 #define PARAM_0 0
25 #define PARAM_5 5
26 #define INIT (-1)
27 #define PARAM_0777 0777
28 
29 static const char *TEMP_FILE = "/data/storage/el2/base/files/fzl.txt";
30 static const char *g_tempFileContent = "This is a test";
31 
FBufSize_One(napi_env env, napi_callback_info info)32 static napi_value FBufSize_One(napi_env env, napi_callback_info info)
33 {
34     napi_value result = nullptr;
35     int ret = INIT;
36     char buf[1024];
37     FILE *fp = nullptr;
38     do {
39         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
40         fp = fdopen(fileDescribe, "r");
41         if (fp == nullptr) {
42             break;
43         }
44         setvbuf(fp, buf, _IOFBF, sizeof(buf));
45         size_t bufsize = __fbufsize(fp);
46         ret = bufsize <= sizeof(buf);
47     } while (PARAM_0);
48     if (fp != nullptr) {
49         fclose(fp);
50     }
51     remove(TEMP_FILE);
52     napi_create_int32(env, ret, &result);
53     return result;
54 }
55 
FBufSize_Two(napi_env env, napi_callback_info info)56 static napi_value FBufSize_Two(napi_env env, napi_callback_info info)
57 {
58     napi_value result = nullptr;
59     int ret = INIT;
60     FILE *fp = nullptr;
61     do {
62         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
63         fp = fdopen(fileDescribe, "r");
64         if (fp == nullptr) {
65             break;
66         }
67         setvbuf(fp, nullptr, _IOFBF, PARAM_0);
68         size_t bufsize = __fbufsize(fp);
69         ret = bufsize == PARAM_0;
70     } while (PARAM_0);
71     if (fp != nullptr) {
72         fclose(fp);
73     }
74     remove(TEMP_FILE);
75     napi_create_int32(env, ret, &result);
76     return result;
77 }
78 
Flbf_One(napi_env env, napi_callback_info info)79 static napi_value Flbf_One(napi_env env, napi_callback_info info)
80 {
81     napi_value result = nullptr;
82     int ret = INIT;
83     char buf[BUFSIZ];
84     FILE *fp = nullptr;
85     do {
86         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
87         fp = fdopen(fileDescribe, "r");
88         if (fp == nullptr) {
89             break;
90         }
91         setvbuf(fp, buf, _IOLBF, sizeof(buf));
92         ret = __flbf(fp);
93     } while (PARAM_0);
94     if (fp != nullptr) {
95         fclose(fp);
96     }
97     remove(TEMP_FILE);
98     napi_create_int32(env, ret, &result);
99     return result;
100 }
101 
Flbf_Two(napi_env env, napi_callback_info info)102 static napi_value Flbf_Two(napi_env env, napi_callback_info info)
103 {
104     napi_value result = nullptr;
105     int ret = INIT;
106     char buf[BUFSIZ];
107     FILE *fp = nullptr;
108     do {
109         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
110         fp = fdopen(fileDescribe, "r");
111         if (fp == nullptr) {
112             break;
113         }
114         setvbuf(fp, buf, _IOFBF, sizeof(buf));
115         ret = __flbf(fp);
116     } while (PARAM_0);
117     if (fp != nullptr) {
118         fclose(fp);
119     }
120     remove(TEMP_FILE);
121     napi_create_int32(env, ret, &result);
122     return result;
123 }
124 
Flbf_Three(napi_env env, napi_callback_info info)125 static napi_value Flbf_Three(napi_env env, napi_callback_info info)
126 {
127     napi_value result = nullptr;
128     int ret = INIT;
129     char buf[BUFSIZ];
130     FILE *fp = nullptr;
131     do {
132         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
133         fp = fdopen(fileDescribe, "r");
134         if (fp == nullptr) {
135             break;
136         }
137         setvbuf(fp, buf, _IONBF, sizeof(buf));
138         ret = __flbf(fp);
139     } while (PARAM_0);
140     if (fp != nullptr) {
141         fclose(fp);
142     }
143     remove(TEMP_FILE);
144     napi_create_int32(env, ret, &result);
145     return result;
146 }
147 
Fpending_One(napi_env env, napi_callback_info info)148 static napi_value Fpending_One(napi_env env, napi_callback_info info)
149 {
150     napi_value result = nullptr;
151     int ret = INIT;
152     FILE *fp = nullptr;
153     do {
154         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
155         fp = fdopen(fileDescribe, "w");
156         if (fp == nullptr) {
157             break;
158         }
159         fputs(g_tempFileContent, fp);
160         ret = __fpending(fp);
161     } while (PARAM_0);
162     if (fp != nullptr) {
163         fclose(fp);
164     }
165     remove(TEMP_FILE);
166     napi_create_int32(env, ret, &result);
167     return result;
168 }
169 
Fpending_Two(napi_env env, napi_callback_info info)170 static napi_value Fpending_Two(napi_env env, napi_callback_info info)
171 {
172     napi_value result = nullptr;
173     int ret = INIT;
174     FILE *fp = nullptr;
175     do {
176         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
177         fp = fdopen(fileDescribe, "w");
178         if (fp == nullptr) {
179             break;
180         }
181         fputs(g_tempFileContent, fp);
182         fflush(fp);
183         ret = __fpending(fp);
184     } while (PARAM_0);
185     if (fp != nullptr) {
186         fclose(fp);
187     }
188     remove(TEMP_FILE);
189     napi_create_int32(env, ret, &result);
190     return result;
191 }
192 
Fpurge_One(napi_env env, napi_callback_info info)193 static napi_value Fpurge_One(napi_env env, napi_callback_info info)
194 {
195     napi_value result = nullptr;
196     int ret = INIT;
197     char buf[100] = {0};
198     FILE *fp = nullptr;
199     do {
200         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
201         fp = fdopen(fileDescribe, "w");
202         if (fp == nullptr) {
203             break;
204         }
205         fputs(g_tempFileContent, fp);
206         ret = __fpurge(fp);
207         fgets(buf, sizeof(buf), fp);
208         ret = strlen(buf);
209     } while (PARAM_0);
210     if (fp != nullptr) {
211         fclose(fp);
212     }
213     remove(TEMP_FILE);
214     napi_create_int32(env, ret, &result);
215     return result;
216 }
217 
Freadable_One(napi_env env, napi_callback_info info)218 static napi_value Freadable_One(napi_env env, napi_callback_info info)
219 {
220     napi_value result = nullptr;
221     int ret = INIT;
222     FILE *fp = nullptr;
223     do {
224         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
225         fp = fdopen(fileDescribe, "r");
226         if (fp == nullptr) {
227             break;
228         }
229         ret = __freadable(fp);
230     } while (PARAM_0);
231     if (fp != nullptr) {
232         fclose(fp);
233     }
234     remove(TEMP_FILE);
235     napi_create_int32(env, !ret, &result);
236     return result;
237 }
238 
Freadable_Two(napi_env env, napi_callback_info info)239 static napi_value Freadable_Two(napi_env env, napi_callback_info info)
240 {
241     napi_value result = nullptr;
242     int ret = INIT;
243     FILE *fp = nullptr;
244     do {
245         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
246         fp = fdopen(fileDescribe, "w");
247         if (fp == nullptr) {
248             break;
249         }
250         ret = __freadable(fp);
251     } while (PARAM_0);
252     if (fp != nullptr) {
253         fclose(fp);
254     }
255     remove(TEMP_FILE);
256     napi_create_int32(env, ret, &result);
257     return result;
258 }
259 
Freading_One(napi_env env, napi_callback_info info)260 static napi_value Freading_One(napi_env env, napi_callback_info info)
261 {
262     napi_value result = nullptr;
263     int ret = INIT;
264     FILE *fp = nullptr;
265     do {
266         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
267         fp = fdopen(fileDescribe, "r");
268         if (fp == nullptr) {
269             break;
270         }
271         ret = __freading(fp);
272     } while (PARAM_0);
273     if (fp != nullptr) {
274         fclose(fp);
275     }
276     remove(TEMP_FILE);
277     napi_create_int32(env, !ret, &result);
278     return result;
279 }
280 
Freading_Two(napi_env env, napi_callback_info info)281 static napi_value Freading_Two(napi_env env, napi_callback_info info)
282 {
283     napi_value result = nullptr;
284     int ret = INIT;
285     FILE *fp = nullptr;
286     do {
287         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
288         fp = fdopen(fileDescribe, "w");
289         if (fp == nullptr) {
290             break;
291         }
292         ret = __freading(fp);
293     } while (PARAM_0);
294     if (fp != nullptr) {
295         fclose(fp);
296     }
297     remove(TEMP_FILE);
298     napi_create_int32(env, ret, &result);
299     return result;
300 }
301 
Fseterr(napi_env env, napi_callback_info info)302 static napi_value Fseterr(napi_env env, napi_callback_info info)
303 {
304     napi_value result = nullptr;
305     int ret = INIT;
306     FILE *fp = nullptr;
307     do {
308         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
309         fp = fdopen(fileDescribe, "w");
310         if (fp == nullptr) {
311             break;
312         }
313         __fseterr(fp);
314         ret = ferror(fp);
315         clearerr(fp);
316     } while (PARAM_0);
317     if (fp != nullptr) {
318         fclose(fp);
319     }
320     remove(TEMP_FILE);
321     napi_create_int32(env, ret, &result);
322     return result;
323 }
324 
Fwritable_One(napi_env env, napi_callback_info info)325 static napi_value Fwritable_One(napi_env env, napi_callback_info info)
326 {
327     napi_value result = nullptr;
328     int ret = INIT;
329     FILE *fp = nullptr;
330     do {
331         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
332         fp = fdopen(fileDescribe, "w");
333         if (fp == nullptr) {
334             break;
335         }
336         ret = __fwritable(fp);
337     } while (PARAM_0);
338     if (fp != nullptr) {
339         fclose(fp);
340     }
341     remove(TEMP_FILE);
342     napi_create_int32(env, !ret, &result);
343     return result;
344 }
345 
Fwritable_Two(napi_env env, napi_callback_info info)346 static napi_value Fwritable_Two(napi_env env, napi_callback_info info)
347 {
348     napi_value result = nullptr;
349     int ret = INIT;
350     FILE *fp = nullptr;
351     do {
352         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
353         fp = fdopen(fileDescribe, "r");
354         if (fp == nullptr) {
355             break;
356         }
357         ret = __fwritable(fp);
358     } while (PARAM_0);
359     if (fp != nullptr) {
360         fclose(fp);
361     }
362     remove(TEMP_FILE);
363     napi_create_int32(env, ret, &result);
364     return result;
365 }
366 
Fwriting_One(napi_env env, napi_callback_info info)367 static napi_value Fwriting_One(napi_env env, napi_callback_info info)
368 {
369     napi_value result = nullptr;
370     int ret = INIT;
371     FILE *fp = nullptr;
372     do {
373         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY);
374         fp = fdopen(fileDescribe, "w");
375         if (fp == nullptr) {
376             break;
377         }
378         ret = __fwriting(fp);
379     } while (PARAM_0);
380     if (fp != nullptr) {
381         fclose(fp);
382     }
383     remove(TEMP_FILE);
384     napi_create_int32(env, !ret, &result);
385     return result;
386 }
387 
Fwriting_Two(napi_env env, napi_callback_info info)388 static napi_value Fwriting_Two(napi_env env, napi_callback_info info)
389 {
390     napi_value result = nullptr;
391     int ret = INIT;
392     FILE *fp = nullptr;
393     do {
394         int fileDescribe = open(TEMP_FILE, O_CREAT, PARAM_0777);
395         fp = fdopen(fileDescribe, "r");
396         if (fp == nullptr) {
397             break;
398         }
399         ret = __fwriting(fp);
400     } while (PARAM_0);
401     if (fp != nullptr) {
402         fclose(fp);
403     }
404     remove(TEMP_FILE);
405     napi_create_int32(env, ret, &result);
406     return result;
407 }
408 
Flushlbf(napi_env env, napi_callback_info info)409 static napi_value Flushlbf(napi_env env, napi_callback_info info)
410 {
411     napi_value result = nullptr;
412     int ret = INIT;
413     FILE *fp = nullptr;
414     char buf[BUFSIZ] = {0};
415     do {
416         int fileDescribe = open(TEMP_FILE, O_CREAT | O_WRONLY | O_TRUNC);
417         fp = fdopen(fileDescribe, "w+");
418         if (fp == nullptr) {
419             break;
420         }
421         setvbuf(fp, buf, _IOLBF, sizeof(buf));
422         fputs(g_tempFileContent, fp);
423         ret = __fpending(fp);
424         if (ret) {
425             _flushlbf();
426             ret = __fpending(fp);
427         } else {
428             ret = !ret;
429         }
430     } while (PARAM_0);
431     if (fp != nullptr) {
432         fclose(fp);
433     }
434     remove(TEMP_FILE);
435     napi_create_int32(env, ret, &result);
436     return result;
437 }
438 
Init(napi_env env, napi_value exports)439 EXTERN_C_START static napi_value Init(napi_env env, napi_value exports)
440 {
441     napi_property_descriptor desc[] = {
442         {"fBufSize_One", nullptr, FBufSize_One, nullptr, nullptr, nullptr, napi_default, nullptr},
443         {"fBufSize_Two", nullptr, FBufSize_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
444         {"fLbf_One", nullptr, Flbf_One, nullptr, nullptr, nullptr, napi_default, nullptr},
445         {"fLbf_Two", nullptr, Flbf_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
446         {"fLbf_Three", nullptr, Flbf_Three, nullptr, nullptr, nullptr, napi_default, nullptr},
447         {"fPending_One", nullptr, Fpending_One, nullptr, nullptr, nullptr, napi_default, nullptr},
448         {"fPending_Two", nullptr, Fpending_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
449         {"fPurge_One", nullptr, Fpurge_One, nullptr, nullptr, nullptr, napi_default, nullptr},
450         {"fReadable_One", nullptr, Freadable_One, nullptr, nullptr, nullptr, napi_default, nullptr},
451         {"fReadable_Two", nullptr, Freadable_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
452         {"fReading_One", nullptr, Freading_One, nullptr, nullptr, nullptr, napi_default, nullptr},
453         {"fReading_Two", nullptr, Freading_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
454         {"fSetErr", nullptr, Fseterr, nullptr, nullptr, nullptr, napi_default, nullptr},
455         {"fWritable_One", nullptr, Fwritable_One, nullptr, nullptr, nullptr, napi_default, nullptr},
456         {"fWritable_Two", nullptr, Fwritable_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
457         {"fWriting_One", nullptr, Fwriting_One, nullptr, nullptr, nullptr, napi_default, nullptr},
458         {"fWriting_Two", nullptr, Fwriting_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
459         {"flushLbf", nullptr, Flushlbf, nullptr, nullptr, nullptr, napi_default, nullptr},
460     };
461     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
462     return exports;
463 }
464 EXTERN_C_END
465 
466 static napi_module demoModule = {
467     .nm_version = 1,
468     .nm_flags = 0,
469     .nm_filename = nullptr,
470     .nm_register_func = Init,
471     .nm_modname = "libstdioextndk1",
472     .nm_priv = ((void *)0),
473     .reserved = {0},
474 };
475 
RegisterModule(void)476 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
477