1 /*
2  * Copyright (c) 2022-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 #include "lstat.h"
16 
17 #include <memory>
18 #include <tuple>
19 
20 #include "class_stat/stat_entity.h"
21 #include "class_stat/stat_n_exporter.h"
22 #include "common_func.h"
23 #include "file_utils.h"
24 #include "filemgmt_libhilog.h"
25 
26 namespace OHOS::FileManagement::ModuleFileIO {
27 using namespace std;
28 using namespace OHOS::FileManagement::LibN;
29 
Sync(napi_env env,napi_callback_info info)30 napi_value Lstat::Sync(napi_env env, napi_callback_info info)
31 {
32     NFuncArg funcArg(env, info);
33     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
34         HILOGE("Number of arguments unmatched");
35         NError(EINVAL).ThrowErr(env);
36         return nullptr;
37     }
38 
39     auto [resGetFirstArg, pathPtr, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
40     if (!resGetFirstArg) {
41         HILOGE("Invalid path");
42         NError(EINVAL).ThrowErr(env);
43         return nullptr;
44     }
45 
46     std::unique_ptr<uv_fs_t, decltype(CommonFunc::fs_req_cleanup)*> lstat_req = {
47         new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup };
48     if (!lstat_req) {
49         HILOGE("Failed to request heap memory.");
50         NError(ENOMEM).ThrowErr(env);
51         return nullptr;
52     }
53     int ret = uv_fs_lstat(nullptr, lstat_req.get(), pathPtr.get(), nullptr);
54     if (ret < 0) {
55         HILOGE("Failed to get stat of file, ret: %{public}d", ret);
56         NError(ret).ThrowErr(env);
57         return nullptr;
58     }
59 
60     auto stat = CommonFunc::InstantiateStat(env, lstat_req->statbuf).val_;
61     return stat;
62 }
63 
LstatExec(shared_ptr<StatEntity> arg,const string & path)64 static NError LstatExec(shared_ptr<StatEntity> arg, const string &path)
65 {
66     std::unique_ptr<uv_fs_t, decltype(CommonFunc::fs_req_cleanup)*> lstat_req = {
67         new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup };
68     if (!lstat_req) {
69         HILOGE("Failed to request heap memory.");
70         return NError(ENOMEM);
71     }
72     int ret = uv_fs_lstat(nullptr, lstat_req.get(), path.c_str(), nullptr);
73     if (ret < 0) {
74         HILOGE("Failed to get stat of file, ret: %{public}d", ret);
75         return NError(ret);
76     } else {
77         arg->stat_ = lstat_req->statbuf;
78         return NError(ERRNO_NOERR);
79     }
80 }
81 
Async(napi_env env,napi_callback_info info)82 napi_value Lstat::Async(napi_env env, napi_callback_info info)
83 {
84     NFuncArg funcArg(env, info);
85     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
86         HILOGE("Number of arguments unmatched");
87         NError(EINVAL).ThrowErr(env);
88         return nullptr;
89     }
90 
91     auto [resGetFirstArg, tmp, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();
92     if (!resGetFirstArg) {
93         HILOGE("Invalid path");
94         NError(EINVAL).ThrowErr(env);
95         return nullptr;
96     }
97 
98     string path = tmp.get();
99     auto arg = CreateSharedPtr<StatEntity>();
100     if (arg == nullptr) {
101         HILOGE("Failed to request heap memory.");
102         NError(ENOMEM).ThrowErr(env);
103         return nullptr;
104     }
105     auto cbExec = [arg, path]() -> NError {
106         return LstatExec(arg, path);
107     };
108 
109     auto cbCompl = [arg](napi_env env, NError err) -> NVal {
110         if (err) {
111             return { env, err.GetNapiErr(env) };
112         }
113         auto stat = CommonFunc::InstantiateStat(env, arg->stat_, true);
114         return stat;
115     };
116 
117     NVal thisVar(env, funcArg.GetThisVar());
118     if (funcArg.GetArgc() == NARG_CNT::ONE) {
119         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_LSTAT_NAME, cbExec, cbCompl).val_;
120     } else {
121         NVal cb(env, funcArg[NARG_POS::SECOND]);
122         return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_LSTAT_NAME, cbExec, cbCompl).val_;
123     }
124 }
125 } // namespace OHOS::FileManagement::ModuleFileIO