1 /*
2  * Copyright (c) 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 "statvfs_n_exporter.h"
17 
18 #include <sys/statvfs.h>
19 #include <tuple>
20 
21 namespace OHOS {
22 namespace FileManagement {
23 namespace ModuleStatvfs {
24 using namespace FileManagement::LibN;
25 
GetFreeSizeSync(napi_env env,napi_callback_info info)26 napi_value GetFreeSizeSync(napi_env env, napi_callback_info info)
27 {
28     NFuncArg funcArg(env, info);
29     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
30         HILOGE("Number of arguments unmatched");
31         NError(EINVAL).ThrowErr(env);
32         return nullptr;
33     }
34 
35     bool succ = false;
36     std::unique_ptr<char[]> path;
37     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
38     if (!succ) {
39         HILOGE("Invalid path");
40         NError(EINVAL).ThrowErr(env);
41         return nullptr;
42     }
43 
44     struct statvfs diskInfo;
45     int ret = statvfs(path.get(), &diskInfo);
46     if (ret != 0) {
47         NError(errno).ThrowErr(env);
48         return nullptr;
49     }
50     unsigned long long freeSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
51                                   static_cast<unsigned long long>(diskInfo.f_bfree);
52     return NVal::CreateInt64(env, freeSize).val_;
53 }
54 
GetFreeSize(napi_env env,napi_callback_info info)55 napi_value GetFreeSize(napi_env env, napi_callback_info info)
56 {
57     NFuncArg funcArg(env, info);
58     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
59         HILOGE("Number of arguments unmatched");
60         NError(EINVAL).ThrowErr(env);
61         return nullptr;
62     }
63 
64     bool succ = false;
65     std::unique_ptr<char []> path;
66     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
67     if (!succ) {
68         HILOGE("Invalid path");
69         NError(EINVAL).ThrowErr(env);
70         return nullptr;
71     }
72 
73     auto resultSize = std::make_shared<unsigned long long>();
74     std::string pathString(path.get());
75     auto cbExec = [pathString = move(pathString), resultSize]() -> NError {
76         struct statvfs diskInfo;
77         int ret = statvfs(pathString.c_str(), &diskInfo);
78         if (ret != 0) {
79             return NError(errno);
80         }
81         *resultSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
82                       static_cast<unsigned long long>(diskInfo.f_bfree);
83         return NError(ERRNO_NOERR);
84     };
85     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
86         if (err) {
87             return { env, err.GetNapiErr(env) };
88         }
89         return NVal::CreateInt64(env, *resultSize);
90     };
91 
92     static const std::string PROCEDURE_NAME = "GetFreeSize";
93     NVal thisVar(env, funcArg.GetThisVar());
94     if (funcArg.GetArgc() == NARG_CNT::ONE) {
95         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
96     }
97 
98     NVal cb(env, funcArg[NARG_POS::SECOND]);
99     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
100 }
101 
GetTotalSizeSync(napi_env env,napi_callback_info info)102 napi_value GetTotalSizeSync(napi_env env, napi_callback_info info)
103 {
104     NFuncArg funcArg(env, info);
105     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
106         HILOGE("Number of arguments unmatched");
107         NError(EINVAL).ThrowErr(env);
108         return nullptr;
109     }
110 
111     bool succ = false;
112     std::unique_ptr<char[]> path;
113     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
114     if (!succ) {
115         HILOGE("Invalid path");
116         NError(EINVAL).ThrowErr(env);
117         return nullptr;
118     }
119 
120     struct statvfs diskInfo;
121     int ret = statvfs(path.get(), &diskInfo);
122     if (ret != 0) {
123         NError(errno).ThrowErr(env);
124         return nullptr;
125     }
126     unsigned long long totalSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
127                                    static_cast<unsigned long long>(diskInfo.f_blocks);
128     return NVal::CreateInt64(env, totalSize).val_;
129 }
130 
GetTotalSize(napi_env env,napi_callback_info info)131 napi_value GetTotalSize(napi_env env, napi_callback_info info)
132 {
133     NFuncArg funcArg(env, info);
134     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
135         HILOGE("Number of arguments unmatched");
136         NError(EINVAL).ThrowErr(env);
137         return nullptr;
138     }
139 
140     bool succ = false;
141     std::unique_ptr<char []> path;
142     tie(succ, path, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
143     if (!succ) {
144         HILOGE("Invalid path");
145         NError(EINVAL).ThrowErr(env);
146         return nullptr;
147     }
148 
149     auto resultSize = std::make_shared<unsigned long long>();
150     std::string pathString(path.get());
151     auto cbExec = [pathString = move(pathString), resultSize]() -> NError {
152         struct statvfs diskInfo;
153         int ret = statvfs(pathString.c_str(), &diskInfo);
154         if (ret != 0) {
155             return NError(errno);
156         }
157         *resultSize = static_cast<unsigned long long>(diskInfo.f_bsize) *
158                       static_cast<unsigned long long>(diskInfo.f_blocks);
159         return NError(ERRNO_NOERR);
160     };
161     auto cbComplete = [resultSize](napi_env env, NError err) -> NVal {
162         if (err) {
163             return { env, err.GetNapiErr(env) };
164         }
165         return { NVal::CreateInt64(env, *resultSize) };
166     };
167 
168     static const std::string PROCEDURE_NAME = "GetTotalSize";
169     NVal thisVar(env, funcArg.GetThisVar());
170     if (funcArg.GetArgc() == NARG_CNT::ONE) {
171         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
172     }
173 
174     NVal cb(env, funcArg[NARG_POS::SECOND]);
175     return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_;
176 }
177 } // namespace ModuleStatfs
178 } // namespace FileManagement
179 } // namespace OHOS
180