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 "stat_n_exporter.h"
17
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <memory>
22 #include <sstream>
23
24 #include "securec.h"
25 #include "../../common/log.h"
26 #include "../../common/napi/n_async/n_async_work_callback.h"
27 #include "../../common/napi/n_async/n_async_work_promise.h"
28 #include "../../common/napi/n_class.h"
29 #include "../../common/napi/n_func_arg.h"
30 #include "../../common/uni_error.h"
31 #include "stat_entity.h"
32
33 namespace OHOS {
34 namespace DistributedFS {
35 namespace ModuleFileIO {
36 using namespace std;
37
CheckStatMode(napi_env env,napi_callback_info info,mode_t mode)38 static napi_value CheckStatMode(napi_env env, napi_callback_info info, mode_t mode)
39 {
40 NFuncArg funcArg(env, info);
41 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
42 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
43 return nullptr;
44 }
45
46 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
47 if (!statEntity) {
48 return nullptr;
49 }
50
51 bool check = (statEntity->stat_.st_mode & S_IFMT) == mode;
52 return NVal::CreateBool(env, check).val_;
53 }
54
IsBlockDevice(napi_env env,napi_callback_info info)55 napi_value StatNExporter::IsBlockDevice(napi_env env, napi_callback_info info)
56 {
57 return CheckStatMode(env, info, S_IFBLK);
58 }
59
IsCharacterDevice(napi_env env,napi_callback_info info)60 napi_value StatNExporter::IsCharacterDevice(napi_env env, napi_callback_info info)
61 {
62 return CheckStatMode(env, info, S_IFCHR);
63 }
64
IsDirectory(napi_env env,napi_callback_info info)65 napi_value StatNExporter::IsDirectory(napi_env env, napi_callback_info info)
66 {
67 return CheckStatMode(env, info, S_IFDIR);
68 }
69
IsFIFO(napi_env env,napi_callback_info info)70 napi_value StatNExporter::IsFIFO(napi_env env, napi_callback_info info)
71 {
72 return CheckStatMode(env, info, S_IFIFO);
73 }
74
IsFile(napi_env env,napi_callback_info info)75 napi_value StatNExporter::IsFile(napi_env env, napi_callback_info info)
76 {
77 return CheckStatMode(env, info, S_IFREG);
78 }
79
IsSocket(napi_env env,napi_callback_info info)80 napi_value StatNExporter::IsSocket(napi_env env, napi_callback_info info)
81 {
82 return CheckStatMode(env, info, S_IFSOCK);
83 }
84
IsSymbolicLink(napi_env env,napi_callback_info info)85 napi_value StatNExporter::IsSymbolicLink(napi_env env, napi_callback_info info)
86 {
87 return CheckStatMode(env, info, S_IFLNK);
88 }
89
GetDev(napi_env env,napi_callback_info info)90 napi_value StatNExporter::GetDev(napi_env env, napi_callback_info info)
91 {
92 NFuncArg funcArg(env, info);
93 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
94 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
95 return nullptr;
96 }
97
98 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
99 if (!statEntity) {
100 return nullptr;
101 }
102
103 return NVal::CreateInt64(env, statEntity->stat_.st_dev).val_;
104 }
105
GetIno(napi_env env,napi_callback_info info)106 napi_value StatNExporter::GetIno(napi_env env, napi_callback_info info)
107 {
108 NFuncArg funcArg(env, info);
109 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
110 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
111 return nullptr;
112 }
113
114 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
115 if (!statEntity) {
116 return nullptr;
117 }
118
119 return NVal::CreateBigInt64(env, statEntity->stat_.st_ino).val_;
120 }
121
GetMode(napi_env env,napi_callback_info info)122 napi_value StatNExporter::GetMode(napi_env env, napi_callback_info info)
123 {
124 NFuncArg funcArg(env, info);
125 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
126 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
127 return nullptr;
128 }
129
130 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
131 if (!statEntity) {
132 return nullptr;
133 }
134
135 return NVal::CreateInt64(env, statEntity->stat_.st_mode).val_;
136 }
137
GetNlink(napi_env env,napi_callback_info info)138 napi_value StatNExporter::GetNlink(napi_env env, napi_callback_info info)
139 {
140 NFuncArg funcArg(env, info);
141 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
142 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
143 return nullptr;
144 }
145
146 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
147 if (!statEntity) {
148 return nullptr;
149 }
150
151 return NVal::CreateInt64(env, statEntity->stat_.st_nlink).val_;
152 }
153
GetUid(napi_env env,napi_callback_info info)154 napi_value StatNExporter::GetUid(napi_env env, napi_callback_info info)
155 {
156 NFuncArg funcArg(env, info);
157 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
158 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
159 return nullptr;
160 }
161
162 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
163 if (!statEntity) {
164 return nullptr;
165 }
166
167 return NVal::CreateInt64(env, statEntity->stat_.st_uid).val_;
168 }
169
GetGid(napi_env env,napi_callback_info info)170 napi_value StatNExporter::GetGid(napi_env env, napi_callback_info info)
171 {
172 NFuncArg funcArg(env, info);
173 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
174 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
175 return nullptr;
176 }
177
178 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
179 if (!statEntity) {
180 return nullptr;
181 }
182
183 return NVal::CreateInt64(env, statEntity->stat_.st_gid).val_;
184 }
185
GetRdev(napi_env env,napi_callback_info info)186 napi_value StatNExporter::GetRdev(napi_env env, napi_callback_info info)
187 {
188 NFuncArg funcArg(env, info);
189 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
190 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
191 return nullptr;
192 }
193
194 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
195 if (!statEntity) {
196 return nullptr;
197 }
198
199 return NVal::CreateInt64(env, statEntity->stat_.st_rdev).val_;
200 }
201
GetSize(napi_env env,napi_callback_info info)202 napi_value StatNExporter::GetSize(napi_env env, napi_callback_info info)
203 {
204 NFuncArg funcArg(env, info);
205 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
206 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
207 return nullptr;
208 }
209
210 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
211 if (!statEntity) {
212 return nullptr;
213 }
214
215 return NVal::CreateInt64(env, statEntity->stat_.st_size).val_;
216 }
217
GetBlksize(napi_env env,napi_callback_info info)218 napi_value StatNExporter::GetBlksize(napi_env env, napi_callback_info info)
219 {
220 NFuncArg funcArg(env, info);
221 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
222 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
223 return nullptr;
224 }
225
226 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
227 if (!statEntity) {
228 return nullptr;
229 }
230
231 return NVal::CreateInt64(env, statEntity->stat_.st_blksize).val_;
232 }
233
GetBlocks(napi_env env,napi_callback_info info)234 napi_value StatNExporter::GetBlocks(napi_env env, napi_callback_info info)
235 {
236 NFuncArg funcArg(env, info);
237 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
238 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
239 return nullptr;
240 }
241
242 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
243 if (!statEntity) {
244 return nullptr;
245 }
246
247 return NVal::CreateInt64(env, statEntity->stat_.st_blocks).val_;
248 }
249
GetAtime(napi_env env,napi_callback_info info)250 napi_value StatNExporter::GetAtime(napi_env env, napi_callback_info info)
251 {
252 NFuncArg funcArg(env, info);
253 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
254 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
255 return nullptr;
256 }
257
258 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
259 if (!statEntity) {
260 return nullptr;
261 }
262
263 return NVal::CreateInt64(env, statEntity->stat_.st_atim.tv_sec).val_;
264 }
265
GetMtime(napi_env env,napi_callback_info info)266 napi_value StatNExporter::GetMtime(napi_env env, napi_callback_info info)
267 {
268 NFuncArg funcArg(env, info);
269 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
270 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
271 return nullptr;
272 }
273
274 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
275 if (!statEntity) {
276 return nullptr;
277 }
278
279 return NVal::CreateInt64(env, statEntity->stat_.st_mtim.tv_sec).val_;
280 }
281
GetCtime(napi_env env,napi_callback_info info)282 napi_value StatNExporter::GetCtime(napi_env env, napi_callback_info info)
283 {
284 NFuncArg funcArg(env, info);
285 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
286 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
287 return nullptr;
288 }
289
290 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
291 if (!statEntity) {
292 return nullptr;
293 }
294
295 return NVal::CreateInt64(env, statEntity->stat_.st_ctim.tv_sec).val_;
296 }
297
Constructor(napi_env env,napi_callback_info info)298 napi_value StatNExporter::Constructor(napi_env env, napi_callback_info info)
299 {
300 NFuncArg funcArg(env, info);
301 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
302 UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
303 return nullptr;
304 }
305
306 unique_ptr<StatEntity> statEntity = make_unique<StatEntity>();
307 if (!NClass::SetEntityFor<StatEntity>(env, funcArg.GetThisVar(), move(statEntity))) {
308 UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj stat");
309 return nullptr;
310 }
311 return funcArg.GetThisVar();
312 }
313
Export()314 bool StatNExporter::Export()
315 {
316 vector<napi_property_descriptor> props = {
317 NVal::DeclareNapiFunction("isBlockDevice", IsBlockDevice),
318 NVal::DeclareNapiFunction("isCharacterDevice", IsCharacterDevice),
319 NVal::DeclareNapiFunction("isDirectory", IsDirectory),
320 NVal::DeclareNapiFunction("isFIFO", IsFIFO),
321 NVal::DeclareNapiFunction("isFile", IsFile),
322 NVal::DeclareNapiFunction("isSocket", IsSocket),
323 NVal::DeclareNapiFunction("isSymbolicLink", IsSymbolicLink),
324
325 NVal::DeclareNapiGetter("dev", GetDev),
326 NVal::DeclareNapiGetter("ino", GetIno),
327 NVal::DeclareNapiGetter("mode", GetMode),
328 NVal::DeclareNapiGetter("nlink", GetNlink),
329 NVal::DeclareNapiGetter("uid", GetUid),
330 NVal::DeclareNapiGetter("gid", GetGid),
331 NVal::DeclareNapiGetter("rdev", GetRdev),
332 NVal::DeclareNapiGetter("size", GetSize),
333 NVal::DeclareNapiGetter("blksize", GetBlksize),
334 NVal::DeclareNapiGetter("blocks", GetBlocks),
335 NVal::DeclareNapiGetter("atime", GetAtime),
336 NVal::DeclareNapiGetter("mtime", GetMtime),
337 NVal::DeclareNapiGetter("ctime", GetCtime),
338 };
339
340 string className = GetClassName();
341 bool succ = false;
342 napi_value classValue = nullptr;
343 tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, StatNExporter::Constructor, std::move(props));
344 if (!succ) {
345 UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class");
346 return false;
347 }
348 succ = NClass::SaveClass(exports_.env_, className, classValue);
349 if (!succ) {
350 UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class");
351 return false;
352 }
353
354 return exports_.AddProp(className, classValue);
355 }
356
GetClassName()357 string StatNExporter::GetClassName()
358 {
359 return StatNExporter::className_;
360 }
361
StatNExporter(napi_env env,napi_value exports)362 StatNExporter::StatNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}
363
~StatNExporter()364 StatNExporter::~StatNExporter() {}
365 } // namespace ModuleFileIO
366 } // namespace DistributedFS
367 } // namespace OHOS
368