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 "fsync.h"
17 
18 #include <cstring>
19 #include <tuple>
20 #include <unistd.h>
21 
22 #include "common_func.h"
23 #include "filemgmt_libhilog.h"
24 
25 namespace OHOS::FileManagement::ModuleFileIO {
26 using namespace std;
27 using namespace OHOS::FileManagement::LibN;
28 
Sync(napi_env env,napi_callback_info info)29 napi_value Fsync::Sync(napi_env env, napi_callback_info info)
30 {
31     NFuncArg funcArg(env, info);
32     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
33         HILOGE("Number of arguments unmatched");
34         NError(EINVAL).ThrowErr(env);
35         return nullptr;
36     }
37 
38     auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
39     if (!resGetFirstArg) {
40         HILOGE("Invalid fd");
41         NError(EINVAL).ThrowErr(env);
42         return nullptr;
43     }
44 
45     std::unique_ptr<uv_fs_t, decltype(CommonFunc::fs_req_cleanup)*> fsync_req = {
46         new uv_fs_t, CommonFunc::fs_req_cleanup };
47     if (!fsync_req) {
48         HILOGE("Failed to request heap memory.");
49         NError(ENOMEM).ThrowErr(env);
50         return nullptr;
51     }
52     int ret = uv_fs_fsync(nullptr, fsync_req.get(), fd, nullptr);
53     if (ret < 0) {
54         HILOGE("Failed to transfer data associated with file descriptor: %{public}d", fd);
55         NError(ret).ThrowErr(env);
56         return nullptr;
57     }
58     return NVal::CreateUndefined(env).val_;
59 }
60 
Async(napi_env env,napi_callback_info info)61 napi_value Fsync::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, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
71     if (!resGetFirstArg) {
72         HILOGE("Invalid fd");
73         NError(EINVAL).ThrowErr(env);
74         return nullptr;
75     }
76 
77     auto cbExec = [fd = fd]() -> NError {
78         std::unique_ptr<uv_fs_t, decltype(CommonFunc::fs_req_cleanup)*> fsync_req = {
79             new uv_fs_t, CommonFunc::fs_req_cleanup };
80         if (!fsync_req) {
81             HILOGE("Failed to request heap memory.");
82             return NError(ENOMEM);
83         }
84         int ret = uv_fs_fsync(nullptr, fsync_req.get(), fd, nullptr);
85         if (ret < 0) {
86             HILOGE("Failed to transfer data associated with file descriptor: %{public}d", fd);
87             return NError(ret);
88         } else {
89             return NError(ERRNO_NOERR);
90         }
91     };
92 
93     auto cbComplete = [](napi_env env, NError err) -> NVal {
94         if (err) {
95             return {env, err.GetNapiErr(env)};
96         } else {
97             return NVal::CreateUndefined(env);
98         }
99     };
100 
101     size_t argc = funcArg.GetArgc();
102     NVal thisVar(env, funcArg.GetThisVar());
103     if (argc == NARG_CNT::ONE) {
104         return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_FSYNC_NAME, cbExec, cbComplete).val_;
105     } else {
106         NVal cb(env, funcArg[NARG_POS::SECOND]);
107         return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_FSYNC_NAME, cbExec, cbComplete).val_;
108     }
109 }
110 } // namespace OHOS::FileManagement::ModuleFileIO