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