1 /*
2 * Copyright (c) 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
16 #include "mkdtemp.h"
17
18 #include "common_func.h"
19 #include "filemgmt_libhilog.h"
20
21 namespace OHOS {
22 namespace FileManagement {
23 namespace ModuleFileIO {
24 using namespace std;
25 using namespace OHOS::FileManagement::LibN;
26
Sync(napi_env env,napi_callback_info info)27 napi_value Mkdtemp::Sync(napi_env env, napi_callback_info info)
28 {
29 NFuncArg funcArg(env, info);
30 if (!funcArg.InitArgs(NARG_CNT::ONE)) {
31 HILOGE("Number of arguments unmatched");
32 NError(EINVAL).ThrowErr(env);
33 return nullptr;
34 }
35
36 auto [resGetFirstArg, tmp, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String();
37 if (!resGetFirstArg) {
38 HILOGE("Invalid path");
39 NError(EINVAL).ThrowErr(env);
40 return nullptr;
41 }
42
43 string path = tmp.get();
44 std::unique_ptr<uv_fs_t, decltype(CommonFunc::fs_req_cleanup)*> mkdtemp_req = {
45 new uv_fs_t, CommonFunc::fs_req_cleanup };
46 if (!mkdtemp_req) {
47 HILOGE("Failed to request heap memory.");
48 NError(ENOMEM).ThrowErr(env);
49 return nullptr;
50 }
51 int ret = uv_fs_mkdtemp(nullptr, mkdtemp_req.get(), const_cast<char *>(path.c_str()), nullptr);
52 if (ret < 0) {
53 HILOGE("Failed to create a temporary directory with path");
54 NError(errno).ThrowErr(env);
55 return nullptr;
56 }
57
58 return NVal::CreateUTF8String(env, mkdtemp_req->path).val_;
59 }
60
Async(napi_env env,napi_callback_info info)61 napi_value Mkdtemp::Async(napi_env env, napi_callback_info info)
62 {
63 NFuncArg funcArg(env, info);
64 if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
65 HILOGE("Number of arguments unmatched");
66 NError(EINVAL).ThrowErr(env);
67 return nullptr;
68 }
69
70 auto [resGetFirstArg, tmp, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String();
71 if (!resGetFirstArg) {
72 HILOGE("Invalid path");
73 NError(EINVAL).ThrowErr(env);
74 return nullptr;
75 }
76
77 auto arg = make_shared<string>();
78 auto cbExec = [path = string(tmp.get()), arg]() -> NError {
79 std::unique_ptr<uv_fs_t, decltype(CommonFunc::fs_req_cleanup)*> mkdtemp_req = {
80 new uv_fs_t, CommonFunc::fs_req_cleanup };
81 if (!mkdtemp_req) {
82 HILOGE("Failed to request heap memory.");
83 return NError(ENOMEM);
84 }
85 int ret = uv_fs_mkdtemp(nullptr, mkdtemp_req.get(), path.c_str(), nullptr);
86 if (ret < 0) {
87 HILOGE("Failed to create a temporary directory with path");
88 return NError(errno);
89 } else {
90 *arg = mkdtemp_req->path;
91 return NError(ERRNO_NOERR);
92 }
93 };
94
95 auto cbComplete = [arg](napi_env env, NError err) -> NVal {
96 if (err) {
97 return { env, err.GetNapiErr(env) };
98 } else {
99 return NVal::CreateUTF8String(env, *arg);
100 }
101 };
102
103 size_t argc = funcArg.GetArgc();
104 NVal thisVar(env, funcArg.GetThisVar());
105 if (argc == NARG_CNT::ONE) {
106 return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_MKDTEMP_NAME, cbExec, cbComplete).val_;
107 } else {
108 NVal cb(env, funcArg[NARG_POS::SECOND]);
109 return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_MKDTEMP_NAME, cbExec, cbComplete).val_;
110 }
111 }
112 } // namespace ModuleFileIO
113 } // namespace FileManagement
114 } // namespace OHOS
115