• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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