1 /*
2 * Copyright (c) 2025 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_core.h"
17
18 #include <memory>
19 #include <tuple>
20 #include <unistd.h>
21
22 #include "file_utils.h"
23 #include "filemgmt_libhilog.h"
24 #include "fs_stat_entity.h"
25 #include "stat_instantiator.h"
26
27 namespace OHOS::FileManagement::ModuleFileIO {
28 using namespace std;
29
IsPath(const FileInfo & fileInfo)30 static bool IsPath(const FileInfo &fileInfo)
31 {
32 auto path = fileInfo.path.get();
33 if (path == nullptr || strlen(path) == 0) {
34 return false;
35 }
36 return true;
37 }
38
IsFd(const FileInfo & fileInfo)39 static tuple<bool, int32_t> IsFd(const FileInfo &fileInfo)
40 {
41 auto fdg = fileInfo.fdg.get();
42 if (fdg == nullptr) {
43 return make_tuple(false, 0);
44 }
45 return make_tuple(true, fdg->GetFD());
46 }
47
ValidFileInfo(const FileInfo & fileInfo)48 static tuple<bool, FileInfo> ValidFileInfo(const FileInfo &fileInfo)
49 {
50 auto isPath = IsPath(fileInfo);
51 if (isPath) {
52 auto &path = const_cast<std::unique_ptr<char[]> &>(fileInfo.path);
53 return { true, FileInfo { true, move(path), {} } };
54 }
55 auto [isFd, fd] = IsFd(fileInfo);
56 if (isFd) {
57 if (fd < 0) {
58 HILOGE("Invalid fd");
59 return { false, FileInfo { false, {}, {} } };
60 }
61 auto fdg = CreateUniquePtr<DistributedFS::FDGuard>(fd, false);
62 if (fdg == nullptr) {
63 HILOGE("Failed to request heap memory.");
64 return { false, FileInfo { false, {}, {} } };
65 }
66 return { true, FileInfo { false, {}, move(fdg) } };
67 }
68 HILOGE("Invalid parameter");
69 return { false, FileInfo { false, {}, {} } };
70 };
71
CheckFsStat(const FileInfo & fileInfo,uv_fs_t * req)72 static int32_t CheckFsStat(const FileInfo &fileInfo, uv_fs_t *req)
73 {
74 if (fileInfo.isPath) {
75 int ret = uv_fs_stat(nullptr, req, fileInfo.path.get(), nullptr);
76 if (ret < 0) {
77 HILOGD("Failed to stat file with path, ret is %{public}d", ret);
78 return ret;
79 }
80 } else {
81 int ret = uv_fs_fstat(nullptr, req, fileInfo.fdg->GetFD(), nullptr);
82 if (ret < 0) {
83 HILOGE("Failed to stat file with fd, ret is %{public}d", ret);
84 return ret;
85 }
86 }
87 return ERRNO_NOERR;
88 }
89
DoStat(const FileInfo & fileinfo)90 FsResult<FsStat *> StatCore::DoStat(const FileInfo &fileinfo)
91 {
92 auto [succ, info] = ValidFileInfo(fileinfo);
93 if (!succ) {
94 return FsResult<FsStat *>::Error(EINVAL);
95 }
96
97 std::unique_ptr<uv_fs_t, decltype(FsUtils::FsReqCleanup) *> statReq = { new (std::nothrow) uv_fs_t,
98 FsUtils::FsReqCleanup };
99 if (!statReq) {
100 HILOGE("Failed to request heap memory.");
101 return FsResult<FsStat *>::Error(ENOMEM);
102 }
103 auto err = CheckFsStat(info, statReq.get());
104 if (err) {
105 return FsResult<FsStat *>::Error(err);
106 }
107
108 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
109 auto arg = CreateSharedPtr<FileInfo>(move(info));
110 if (arg == nullptr) {
111 HILOGE("Failed to request heap memory.");
112 return FsResult<FsStat *>::Error(ENOMEM);
113 }
114 auto stat = StatInstantiator::InstantiateStat(statReq->statbuf, arg);
115 #else
116 auto stat = StatInstantiator::InstantiateStat(statReq->statbuf);
117 #endif
118 if (stat == nullptr) {
119 return FsResult<FsStat *>::Error(ENOMEM);
120 }
121 return FsResult<FsStat *>::Success(stat);
122 }
123
124 } // namespace OHOS::FileManagement::ModuleFileIO