1 /*
2  * Copyright (c) 2021-2022 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 "statfs_n_exporter.h"
17 
18 #include <sys/statvfs.h>
19 #include <tuple>
20 
21 namespace OHOS {
22 namespace FileManagement {
23 namespace ModuleStatfs {
24 using namespace FileManagement::LibN;
25 
GetFrSizeSync(napi_env env,napi_callback_info info)26 napi_value GetFrSizeSync(napi_env env, napi_callback_info info)
27 {
28     NFuncArg funcArg(env, info);
29     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
30         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
31         return nullptr;
32     }
33 
34     bool succ = false;
35     std::unique_ptr<char[]> path;
36     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
37     if (!succ) {
38         NError(EINVAL).ThrowErr(env, "Invalid path");
39         return nullptr;
40     }
41 
42     struct statvfs diskInfo;
43     int ret = statvfs(path.get(), &diskInfo);
44     if (ret != 0) {
45         NError(errno).ThrowErr(env, "Failed get info");
46         return nullptr;
47     }
48     unsigned long long freeSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
49                                   static_cast<unsigned long long>(diskInfo.f_bavail);
50     return NVal::CreateInt64(env, freeSize).val_;
51 }
52 
GetFrSize(napi_env env,napi_callback_info info)53 napi_value GetFrSize(napi_env env, napi_callback_info info)
54 {
55     NFuncArg funcArg(env, info);
56     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
57         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
58         return nullptr;
59     }
60 
61     bool succ = false;
62     std::unique_ptr<char []> path;
63     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
64     if (!succ) {
65         NError(EINVAL).ThrowErr(env, "Invalid path");
66         return nullptr;
67     }
68 
69     auto resultSize = std::make_shared<unsigned long long>();
70     std::string pathString(path.get());
71     auto cbExec = [pathString, resultSize]() -> NError {
72         struct statvfs diskInfo;
73         int ret = statvfs(pathString.c_str(), &diskInfo);
74         if (ret != 0) {
75             return NError(errno);
76         }
77         *resultSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
78                       static_cast<unsigned long long>(diskInfo.f_bavail);
79         return NError(ERRNO_NOERR);
80     };
81     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
82         if (err) {
83             return { env, err.GetNapiErr(env) };
84         }
85         return NVal::CreateInt64(env, *resultSize);
86     };
87 
88     static const std::string PROCEDURE_NAME = "GetFrSize";
89     NVal thisVar(env, funcArg.GetThisVar());
90     if (funcArg.GetArgc() == NARG_CNT::ONE) {
91         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
92     }
93 
94     NVal cb(env, funcArg[NARG_POS::SECOND]);
95     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
96 }
97 
GetBSizeSync(napi_env env,napi_callback_info info)98 napi_value GetBSizeSync(napi_env env, napi_callback_info info)
99 {
100     NFuncArg funcArg(env, info);
101     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
102         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
103         return nullptr;
104     }
105 
106     bool succ = false;
107     std::unique_ptr<char[]> path;
108     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
109     if (!succ) {
110         NError(EINVAL).ThrowErr(env, "Invalid path");
111         return nullptr;
112     }
113 
114     struct statvfs diskInfo;
115     int ret = statvfs(path.get(), &diskInfo);
116     if (ret != 0) {
117         NError(errno).ThrowErr(env);
118         return nullptr;
119     }
120     return NVal::CreateInt64(env, diskInfo.f_bsize).val_;
121 }
122 
GetBSize(napi_env env,napi_callback_info info)123 napi_value GetBSize(napi_env env, napi_callback_info info)
124 {
125     NFuncArg funcArg(env, info);
126     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
127         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
128         return nullptr;
129     }
130 
131     bool succ = false;
132     std::unique_ptr<char []> path;
133     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
134     if (!succ) {
135         NError(EINVAL).ThrowErr(env, "Invalid path");
136         return nullptr;
137     }
138 
139     auto resultSize = std::make_shared<unsigned long long>();
140     std::string pathString(path.get());
141     auto cbExec = [pathString, resultSize]() -> NError {
142         struct statvfs diskInfo;
143         int ret = statvfs(pathString.c_str(), &diskInfo);
144         if (ret != 0) {
145             return NError(errno);
146         }
147         *resultSize = diskInfo.f_bsize;
148         return NError(ERRNO_NOERR);
149     };
150     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
151         if (err) {
152             return { env, err.GetNapiErr(env) };
153         }
154         return NVal::CreateInt64(env, *resultSize);
155     };
156 
157     static const std::string PROCEDURE_NAME = "GetBSize";
158     NVal thisVar(env, funcArg.GetThisVar());
159     if (funcArg.GetArgc() == NARG_CNT::ONE) {
160         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
161     }
162 
163     NVal cb(env, funcArg[NARG_POS::SECOND]);
164     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
165 }
166 
GetBAvailSync(napi_env env,napi_callback_info info)167 napi_value GetBAvailSync(napi_env env, napi_callback_info info)
168 {
169     NFuncArg funcArg(env, info);
170     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
171         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
172         return nullptr;
173     }
174 
175     bool succ = false;
176     std::unique_ptr<char[]> path;
177     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
178     if (!succ) {
179         NError(EINVAL).ThrowErr(env, "Invalid path");
180         return nullptr;
181     }
182 
183     struct statvfs diskInfo;
184     int ret = statvfs(path.get(), &diskInfo);
185     if (ret != 0) {
186         NError(errno).ThrowErr(env);
187         return nullptr;
188     }
189     return NVal::CreateInt64(env, diskInfo.f_bavail).val_;
190 }
191 
GetBAvail(napi_env env,napi_callback_info info)192 napi_value GetBAvail(napi_env env, napi_callback_info info)
193 {
194     NFuncArg funcArg(env, info);
195     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
196         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
197         return nullptr;
198     }
199 
200     bool succ = false;
201     std::unique_ptr<char []> path;
202     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
203     if (!succ) {
204         NError(EINVAL).ThrowErr(env, "Invalid path");
205         return nullptr;
206     }
207 
208     auto resultSize = std::make_shared<unsigned long long>();
209     std::string pathString(path.get());
210     auto cbExec = [pathString, resultSize]() -> NError {
211         struct statvfs diskInfo;
212         int ret = statvfs(pathString.c_str(), &diskInfo);
213         if (ret != 0) {
214             return NError(errno);
215         }
216         *resultSize = diskInfo.f_bavail;
217         return NError(ERRNO_NOERR);
218     };
219     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
220         if (err) {
221             return { env, err.GetNapiErr(env) };
222         }
223         return NVal::CreateInt64(env, *resultSize);
224     };
225 
226     static const std::string PROCEDURE_NAME = "GetBAvail";
227     NVal thisVar(env, funcArg.GetThisVar());
228     if (funcArg.GetArgc() == NARG_CNT::ONE) {
229         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
230     }
231 
232     NVal cb(env, funcArg[NARG_POS::SECOND]);
233     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
234 }
235 
GetBlocksSync(napi_env env,napi_callback_info info)236 napi_value GetBlocksSync(napi_env env, napi_callback_info info)
237 {
238     NFuncArg funcArg(env, info);
239     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
240         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
241         return nullptr;
242     }
243 
244     bool succ = false;
245     std::unique_ptr<char[]> path;
246     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
247     if (!succ) {
248         NError(EINVAL).ThrowErr(env, "Invalid path");
249         return nullptr;
250     }
251 
252     struct statvfs diskInfo;
253     int ret = statvfs(path.get(), &diskInfo);
254     if (ret != 0) {
255         NError(errno).ThrowErr(env);
256         return nullptr;
257     }
258     return NVal::CreateInt64(env, diskInfo.f_blocks).val_;
259 }
260 
GetBlocks(napi_env env,napi_callback_info info)261 napi_value GetBlocks(napi_env env, napi_callback_info info)
262 {
263     NFuncArg funcArg(env, info);
264     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
265         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
266         return nullptr;
267     }
268 
269     bool succ = false;
270     std::unique_ptr<char []> path;
271     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
272     if (!succ) {
273         NError(EINVAL).ThrowErr(env, "Invalid path");
274         return nullptr;
275     }
276 
277     auto resultSize = std::make_shared<unsigned long long>();
278     std::string pathString(path.get());
279     auto cbExec = [pathString, resultSize]() -> NError {
280         struct statvfs diskInfo;
281         int ret = statvfs(pathString.c_str(), &diskInfo);
282         if (ret != 0) {
283             return NError(errno);
284         }
285         *resultSize = diskInfo.f_blocks;
286         return NError(ERRNO_NOERR);
287     };
288     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
289         if (err) {
290             return { env, err.GetNapiErr(env) };
291         }
292         return NVal::CreateInt64(env, *resultSize);
293     };
294 
295     static const std::string PROCEDURE_NAME = "GetBlocks";
296     NVal thisVar(env, funcArg.GetThisVar());
297     if (funcArg.GetArgc() == NARG_CNT::ONE) {
298         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
299     }
300 
301     NVal cb(env, funcArg[NARG_POS::SECOND]);
302     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
303 }
304 
GetBFreeSync(napi_env env,napi_callback_info info)305 napi_value GetBFreeSync(napi_env env, napi_callback_info info)
306 {
307     NFuncArg funcArg(env, info);
308     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
309         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
310         return nullptr;
311     }
312 
313     bool succ = false;
314     std::unique_ptr<char[]> path;
315     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
316     if (!succ) {
317         NError(EINVAL).ThrowErr(env, "Invalid path");
318         return nullptr;
319     }
320 
321     struct statvfs diskInfo;
322     int ret = statvfs(path.get(), &diskInfo);
323     if (ret != 0) {
324         NError(errno).ThrowErr(env);
325         return nullptr;
326     }
327     return NVal::CreateInt64(env, diskInfo.f_bfree).val_;
328 }
329 
GetBFree(napi_env env,napi_callback_info info)330 napi_value GetBFree(napi_env env, napi_callback_info info)
331 {
332     NFuncArg funcArg(env, info);
333     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
334         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
335         return nullptr;
336     }
337 
338     bool succ = false;
339     std::unique_ptr<char []> path;
340     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
341     if (!succ) {
342         NError(EINVAL).ThrowErr(env, "Invalid path");
343         return nullptr;
344     }
345 
346     auto resultSize = std::make_shared<unsigned long long>();
347     std::string pathString(path.get());
348     auto cbExec = [pathString, resultSize]() -> NError {
349         struct statvfs diskInfo;
350         int ret = statvfs(pathString.c_str(), &diskInfo);
351         if (ret != 0) {
352             return NError(errno);
353         }
354         *resultSize = diskInfo.f_bfree;
355         return NError(ERRNO_NOERR);
356     };
357     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
358         if (err) {
359             return { env, err.GetNapiErr(env) };
360         }
361         return NVal::CreateInt64(env, *resultSize);
362     };
363 
364     static const std::string PROCEDURE_NAME = "GetBFree";
365     NVal thisVar(env, funcArg.GetThisVar());
366     if (funcArg.GetArgc() == NARG_CNT::ONE) {
367         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
368     }
369 
370     NVal cb(env, funcArg[NARG_POS::SECOND]);
371     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
372 }
373 
GetFreeBytesSync(napi_env env,napi_callback_info info)374 napi_value GetFreeBytesSync(napi_env env, napi_callback_info info)
375 {
376     NFuncArg funcArg(env, info);
377     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
378         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
379         return nullptr;
380     }
381 
382     bool succ = false;
383     std::unique_ptr<char[]> path;
384     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
385     if (!succ) {
386         NError(EINVAL).ThrowErr(env, "Invalid path");
387         return nullptr;
388     }
389 
390     struct statvfs diskInfo;
391     int ret = statvfs(path.get(), &diskInfo);
392     if (ret != 0) {
393         NError(errno).ThrowErr(env);
394         return nullptr;
395     }
396     unsigned long long freeSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
397                                   static_cast<unsigned long long>(diskInfo.f_bfree);
398     return NVal::CreateInt64(env, freeSize).val_;
399 }
400 
GetFreeBytes(napi_env env,napi_callback_info info)401 napi_value GetFreeBytes(napi_env env, napi_callback_info info)
402 {
403     NFuncArg funcArg(env, info);
404     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
405         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
406         return nullptr;
407     }
408 
409     bool succ = false;
410     std::unique_ptr<char []> path;
411     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
412     if (!succ) {
413         NError(EINVAL).ThrowErr(env, "Invalid path");
414         return nullptr;
415     }
416 
417     auto resultSize = std::make_shared<unsigned long long>();
418     std::string pathString(path.get());
419     auto cbExec = [pathString, resultSize]() -> NError {
420         struct statvfs diskInfo;
421         int ret = statvfs(pathString.c_str(), &diskInfo);
422         if (ret != 0) {
423             return NError(errno);
424         }
425         *resultSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
426                       static_cast<unsigned long long>(diskInfo.f_bfree);
427         return NError(ERRNO_NOERR);
428     };
429     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
430         if (err) {
431             return { env, err.GetNapiErr(env) };
432         }
433         return NVal::CreateInt64(env, *resultSize);
434     };
435 
436     static const std::string PROCEDURE_NAME = "GetFreeBytes";
437     NVal thisVar(env, funcArg.GetThisVar());
438     if (funcArg.GetArgc() == NARG_CNT::ONE) {
439         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
440     }
441 
442     NVal cb(env, funcArg[NARG_POS::SECOND]);
443     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
444 }
445 
GetTotalBytesSync(napi_env env,napi_callback_info info)446 napi_value GetTotalBytesSync(napi_env env, napi_callback_info info)
447 {
448     NFuncArg funcArg(env, info);
449     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
450         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
451         return nullptr;
452     }
453 
454     bool succ = false;
455     std::unique_ptr<char[]> path;
456     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
457     if (!succ) {
458         NError(EINVAL).ThrowErr(env, "Invalid path");
459         return nullptr;
460     }
461 
462     struct statvfs diskInfo;
463     int ret = statvfs(path.get(), &diskInfo);
464     if (ret != 0) {
465         NError(errno).ThrowErr(env);
466         return nullptr;
467     }
468     unsigned long long totalSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
469                                    static_cast<unsigned long long>(diskInfo.f_blocks);
470     return NVal::CreateInt64(env, totalSize).val_;
471 }
472 
GetTotalBytes(napi_env env,napi_callback_info info)473 napi_value GetTotalBytes(napi_env env, napi_callback_info info)
474 {
475     NFuncArg funcArg(env, info);
476     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
477         NError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
478         return nullptr;
479     }
480 
481     bool succ = false;
482     std::unique_ptr<char []> path;
483     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
484     if (!succ) {
485         NError(EINVAL).ThrowErr(env, "Invalid path");
486         return nullptr;
487     }
488 
489     auto resultSize = std::make_shared<unsigned long long>();
490     std::string pathString(path.get());
491     auto cbExec = [pathString, resultSize]() -> NError {
492         struct statvfs diskInfo;
493         int ret = statvfs(pathString.c_str(), &diskInfo);
494         if (ret != 0) {
495             return NError(errno);
496         }
497         *resultSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
498                       static_cast<unsigned long long>(diskInfo.f_blocks);
499         return NError(ERRNO_NOERR);
500     };
501     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
502         if (err) {
503             return { env, err.GetNapiErr(env) };
504         }
505         return { NVal::CreateInt64(env, *resultSize) };
506     };
507 
508     static const std::string PROCEDURE_NAME = "GetTotalBytes";
509     NVal thisVar(env, funcArg.GetThisVar());
510     if (funcArg.GetArgc() == NARG_CNT::ONE) {
511         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
512     }
513 
514     NVal cb(env, funcArg[NARG_POS::SECOND]);
515     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
516 }
517 } // namespace ModuleStatfs
518 } // namespace FileManagement
519 } // namespace OHOS
520