• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "res_sched_file_util.h"
17 
18 #include <system_error>
19 #include <cstring>
20 #include <dirent.h>
21 #include <fstream>
22 #include <filesystem>
23 
24 #include "config_policy_utils.h"
25 #include "directory_ex.h"
26 #include "file_ex.h"
27 #include "res_sched_log.h"
28 
29 namespace OHOS {
30 namespace ResourceSchedule {
31 namespace ResCommonUtil {
WriteFileReclaim(int32_t pid)32 void WriteFileReclaim(int32_t pid)
33 {
34     std::string path = "/proc/" + std::to_string(pid) + "/reclaim";
35     std::string contentStr = "1";
36     int fd = open(path.c_str(), O_WRONLY);
37     // judge whether open failed
38     if (fd < 0) {
39         RESSCHED_LOGE("%{public}s: open failed.", __func__);
40         return;
41     }
42     // write content to fd
43     write(fd, contentStr.c_str(), contentStr.length());
44     close(fd);
45 }
46 
GetRealPath(const std::string & filePath,std::string & realPath)47 bool GetRealPath(const std::string& filePath, std::string& realPath)
48 {
49     if (!OHOS::PathToRealPath(filePath, realPath)) {
50         RESSCHED_LOGE("%{public}s: get real path failed.", __func__);
51         return false;
52     }
53     return true;
54 }
55 
PathOrFileExists(const std::string & path)56 bool PathOrFileExists(const std::string& path)
57 {
58     if (access(path.c_str(), F_OK) != 0) {
59         RESSCHED_LOGE("%{public}s: access failed.", __func__);
60         return false;
61     }
62     return true;
63 }
64 
DirIterator(const std::string & filePath,std::vector<std::string> & iters)65 bool DirIterator(const std::string& filePath, std::vector<std::string>& iters)
66 {
67     DIR *dir = opendir(filePath.c_str());
68     // input invaild, open failed
69     if (dir == nullptr) {
70         RESSCHED_LOGE("%{public}s: open failed.", __func__);
71         return false;
72     }
73     struct dirent *ptr;
74     while ((ptr = readdir(dir)) != nullptr) {
75         // current dir is path of '.' or '..'
76         if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
77             RESSCHED_LOGD("%{public}s: skip current and pre path", __func__);
78             continue;
79         }
80         iters.emplace_back(IncludeTrailingPathDelimiter(filePath) + std::string(ptr->d_name));
81     }
82     closedir(dir);
83     return true;
84 }
85 
IsEmptyDir(const std::string & filePath)86 bool IsEmptyDir(const std::string& filePath)
87 {
88     return OHOS::IsEmptyFolder(filePath);
89 }
90 
IsDir(const std::string & filePath)91 bool IsDir(const std::string& filePath)
92 {
93     struct stat info{};
94     // dose not exist
95     if (stat(filePath.c_str(), &info) != 0) {
96         RESSCHED_LOGE("%{public}s: file path not exist.", __func__);
97         return false;
98     }
99     // is not directory
100     if (!(info.st_mode & S_IFDIR)) {
101         return false;
102     }
103     return true;
104 }
105 
CreateDir(const std::string & dir,const mode_t & mode)106 bool CreateDir(const std::string& dir, const mode_t& mode)
107 {
108     // create directory
109     if (!OHOS::ForceCreateDirectory(dir)) {
110         RESSCHED_LOGE("%{public}s: Failed to create dir", __func__);
111         return false;
112     }
113     // change directory's mode.
114     if (!OHOS::ChangeModeDirectory(dir, mode)) {
115         RESSCHED_LOGE("%{public}s: Failed to change dir mode to %{public}ud", __func__,
116             mode);
117         // if change failed, remove it.
118         RemoveDirs(dir);
119         return false;
120     }
121     return true;
122 }
123 
CreateFile(const std::string & filePath,const mode_t & mode)124 bool CreateFile(const std::string& filePath, const mode_t& mode)
125 {
126     std::ofstream fd;
127     // create and open file.
128     fd.open(filePath);
129     if (!fd.is_open()) {
130         //create filed
131         RESSCHED_LOGE("%{public}s: Failed to create file", __func__);
132         return false;
133     }
134     fd.close();
135 
136     //change file mode
137     if (!OHOS::ChangeModeFile(filePath, mode)) {
138         //change failed
139         RESSCHED_LOGE("%{public}s: Failed to change file mode to %{public}ud", __func__,
140             mode);
141         RemoveFile(filePath);
142         return false;
143     }
144     return true;
145 }
146 
RemoveDirs(const std::string & dir)147 bool RemoveDirs(const std::string& dir)
148 {
149     if (!OHOS::ForceRemoveDirectory(dir)) {
150         RESSCHED_LOGE("%{public}s: Failed to remove dir", __func__);
151         return false;
152     }
153     return true;
154 }
155 
RemoveFile(const std::string & filePath)156 bool RemoveFile(const std::string& filePath)
157 {
158     if (!OHOS::RemoveFile(filePath)) {
159         RESSCHED_LOGE("%{public}s: Failed to remove file", __func__);
160         return false;
161     }
162     return true;
163 }
164 
ExtractFileName(const std::string & filePath)165 std::string ExtractFileName(const std::string& filePath)
166 {
167     return OHOS::ExtractFileName(filePath);
168 }
169 
IsBLKPath(const std::string & filePath)170 bool IsBLKPath(const std::string& filePath)
171 {
172     struct stat sb;
173     if (stat(filePath.c_str(), &sb) == 0 && S_ISBLK(sb.st_mode)) {
174         return true;
175     }
176     return false;
177 }
178 
SaveStringToFile(const std::string & filePath,const std::string & content,bool truncated)179 bool SaveStringToFile(const std::string& filePath, const std::string& content, bool truncated)
180 {
181     return OHOS::SaveStringToFile(filePath, content, truncated);
182 }
183 
ReadLinesFromFile(const std::string & filePath,std::vector<std::string> & lines)184 bool ReadLinesFromFile(const std::string& filePath, std::vector<std::string>& lines)
185 {
186     std::string line;
187     char tmpPath[PATH_MAX + 1] = {0};
188     auto len = filePath.length();
189     if (len == 0 || len > PATH_MAX || !realpath(filePath.c_str(), tmpPath)) {
190         RESSCHED_LOGE("%{public}s: file path invalid", __func__);
191         return false;
192     }
193     std::string realConfigPath(tmpPath);
194     std::ifstream fin(realConfigPath, std::ifstream::in);
195     // judge whether open failed.
196     if (!fin) {
197         RESSCHED_LOGE("%{public}s: open file failed.", __func__);
198         return false;
199     }
200     // clear container and read lines
201     lines.clear();
202     while (fin.peek() != EOF) {
203         getline(fin, line);
204         lines.emplace_back(line);
205     }
206     fin.close();
207     return true;
208 }
209 
DoCopy(const std::string & src,const std::string & des)210 bool DoCopy(const std::string& src, const std::string& des)
211 {
212     std::filesystem::path sPath(src);
213     std::filesystem::path dPath(des);
214     std::error_code errNo;
215 
216     const auto copyOptions = std::filesystem::copy_options::overwrite_existing |
217         std::filesystem::copy_options::recursive |
218         std::filesystem::copy_options::skip_symlinks;
219     std::filesystem::copy(sPath, dPath, copyOptions, errNo);
220     // if has some error in copy, record errno
221     if (errNo.value()) {
222         RESSCHED_LOGE("copy failed errno:%{public}d", errNo.value());
223         return false;
224     }
225     RESSCHED_LOGD("copy success");
226     return true;
227 }
228 
CopyFile(const std::string & src,const std::string & des)229 bool CopyFile(const std::string& src, const std::string& des)
230 {
231     // judge src exist.
232     if (!PathOrFileExists(src)) {
233         RESSCHED_LOGE("%{public}s: src path invalid!", __func__);
234         return false;
235     }
236     if (PathOrFileExists(des)) {
237         // target path is exist, remove it before copy.
238         if (!RemoveDirs(des)) {
239             RESSCHED_LOGE("%{public}s: target path is exist and remove failed!", __func__);
240             return false;
241         }
242     }
243     errno = 0;
244     // create target directory.
245     if (mkdir(des.c_str(), S_IRWXU) != 0 && errno != EEXIST) {
246         RESSCHED_LOGE("%{public}s: create target path failed!", __func__);
247         return false;
248     }
249     // do real copy action.
250     return DoCopy(src, des);
251 }
252 
GetRealConfigPath(const std::string & configPath,std::string & realConfigPath)253 bool GetRealConfigPath(const std::string& configPath, std::string& realConfigPath)
254 {
255     // judge input path vaild.
256     if (configPath.empty()) {
257         RESSCHED_LOGE("%{public}s:the input config path is empty", __func__);
258         return false;
259     }
260     char buf[PATH_MAX];
261     char* tmpPath = GetOneCfgFile(configPath.c_str(), buf, PATH_MAX);
262     char absolutePath[PATH_MAX] = {0};
263     // if config path is vaild, obtain real path.
264     if (!tmpPath || strlen(tmpPath) > PATH_MAX || !realpath(tmpPath, absolutePath)) {
265         RESSCHED_LOGE("%{public}s:get one config file failed", __func__);
266         return false;
267     }
268     realConfigPath = std::string(absolutePath);
269     return true;
270 }
271 }
272 } // namespace ResourceSchedule
273 } // namespace OHOS
274