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