1 /*
2 * Copyright (c) 2021 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 "file_util.h"
17
18 #include <cstdint>
19 #include <cstdio>
20 #include <cstring>
21 #include <dirent.h>
22 #include <fcntl.h>
23 #include <fstream>
24 #include <istream>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <vector>
28
29 #include "directory_ex.h"
30 #include "file_ex.h"
31
32 namespace OHOS {
33 namespace HiviewDFX {
34 namespace FileUtil {
35 using namespace std;
LoadStringFromFile(const std::string & filePath,std::string & content)36 bool LoadStringFromFile(const std::string& filePath, std::string& content)
37 {
38 return OHOS::LoadStringFromFile(filePath, content);
39 }
40
LoadLinesFromFile(const std::string & filePath,std::vector<std::string> & lines)41 bool LoadLinesFromFile(const std::string& filePath, std::vector<std::string>& lines)
42 {
43 std::ifstream file(filePath);
44 if (file.is_open()) {
45 std::string line;
46 while (std::getline(file, line)) {
47 lines.emplace_back(line);
48 }
49 file.close();
50 return true;
51 }
52 return false;
53 }
54
LoadStringFromFd(int fd,std::string & content)55 bool LoadStringFromFd(int fd, std::string& content)
56 {
57 return OHOS::LoadStringFromFd(fd, content);
58 }
59
SaveStringToFile(const std::string & filePath,const std::string & content,bool truncated)60 bool SaveStringToFile(const std::string& filePath, const std::string& content, bool truncated)
61 {
62 return OHOS::SaveStringToFile(filePath, content, truncated);
63 }
64
SaveStringToFd(int fd,const std::string & content)65 bool SaveStringToFd(int fd, const std::string& content)
66 {
67 return OHOS::SaveStringToFd(fd, content);
68 }
69
LoadBufferFromFile(const std::string & filePath,std::vector<char> & content)70 bool LoadBufferFromFile(const std::string& filePath, std::vector<char>& content)
71 {
72 return OHOS::LoadBufferFromFile(filePath, content);
73 }
74
SaveBufferToFile(const std::string & filePath,const std::vector<char> & content,bool truncated)75 bool SaveBufferToFile(const std::string& filePath, const std::vector<char>& content, bool truncated)
76 {
77 return OHOS::SaveBufferToFile(filePath, content, truncated);
78 }
79
FileExists(const std::string & fileName)80 bool FileExists(const std::string& fileName)
81 {
82 return OHOS::FileExists(fileName);
83 }
84
ExtractFilePath(const std::string & fileFullName)85 std::string ExtractFilePath(const std::string& fileFullName)
86 {
87 return OHOS::ExtractFilePath(fileFullName);
88 }
89
ExtractFileName(const std::string & fileFullName)90 std::string ExtractFileName(const std::string& fileFullName)
91 {
92 return OHOS::ExtractFileName(fileFullName);
93 }
94
ExtractFileExt(const std::string & fileName)95 std::string ExtractFileExt(const std::string& fileName)
96 {
97 return OHOS::ExtractFileExt(fileName);
98 }
99
IncludeTrailingPathDelimiter(const std::string & path)100 std::string IncludeTrailingPathDelimiter(const std::string& path)
101 {
102 return OHOS::IncludeTrailingPathDelimiter(path);
103 }
104
ExcludeTrailingPathDelimiter(const std::string & path)105 std::string ExcludeTrailingPathDelimiter(const std::string& path)
106 {
107 return OHOS::ExcludeTrailingPathDelimiter(path);
108 }
109
GetDirFiles(const std::string & path,std::vector<std::string> & files,bool isRecursive)110 void GetDirFiles(const std::string& path, std::vector<std::string>& files, bool isRecursive)
111 {
112 DIR* dir = opendir(path.c_str());
113 if (dir == nullptr) {
114 return;
115 }
116
117 while (true) {
118 struct dirent* ptr = readdir(dir);
119 if (ptr == nullptr) {
120 break;
121 }
122
123 // current dir or parent dir
124 if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
125 continue;
126 } else if (ptr->d_type == DT_DIR && isRecursive) {
127 std::string pathStringWithDelimiter = IncludeTrailingPathDelimiter(path) + string(ptr->d_name);
128 GetDirFiles(pathStringWithDelimiter, files);
129 } else {
130 files.push_back(IncludeTrailingPathDelimiter(path) + string(ptr->d_name));
131 }
132 }
133 closedir(dir);
134 }
135
GetDirDirs(const std::string & path,std::vector<std::string> & dirs)136 void GetDirDirs(const std::string& path, std::vector<std::string>& dirs)
137 {
138 DIR* dir = opendir(path.c_str());
139 if (dir == nullptr) {
140 return;
141 }
142
143 while (true) {
144 struct dirent *ptr = readdir(dir);
145 if (ptr == nullptr) {
146 break;
147 }
148 if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
149 continue;
150 } else if (ptr->d_type == DT_DIR) {
151 dirs.push_back(IncludeTrailingPathDelimiter(path) + string(ptr->d_name));
152 }
153 }
154 closedir(dir);
155 }
156
ForceCreateDirectory(const std::string & path)157 bool ForceCreateDirectory(const std::string& path)
158 {
159 return OHOS::ForceCreateDirectory(path);
160 }
161
ForceCreateDirectory(const string & path,mode_t mode)162 bool ForceCreateDirectory(const string& path, mode_t mode)
163 {
164 string::size_type index = 0;
165 do {
166 index = path.find('/', index + 1);
167 string subPath = (index == string::npos) ? path : path.substr(0, index);
168 if (access(subPath.c_str(), F_OK) != 0) {
169 if (mkdir(subPath.c_str(), mode) != 0) {
170 return false;
171 }
172 }
173 } while (index != string::npos);
174 return access(path.c_str(), F_OK) == 0;
175 }
176
ForceRemoveDirectory(const std::string & path,bool isNeedDeleteGivenDirSelf)177 bool ForceRemoveDirectory(const std::string& path, bool isNeedDeleteGivenDirSelf)
178 {
179 return OHOS::ForceRemoveDirectory(path);
180 }
181
GetFileSize(const std::string & path)182 uint64_t GetFileSize(const std::string& path)
183 {
184 struct stat st;
185 return stat(path.c_str(), &st) ? 0 : static_cast<uint64_t>(st.st_size);
186 }
187
RemoveFile(const std::string & fileName)188 bool RemoveFile(const std::string& fileName)
189 {
190 return OHOS::RemoveFile(fileName);
191 }
192
GetFolderSize(const std::string & path)193 uint64_t GetFolderSize(const std::string& path)
194 {
195 return OHOS::GetFolderSize(path);
196 }
197
198 // inner function, and param is legitimate
ChangeMode(const string & fileName,const mode_t & mode)199 bool ChangeMode(const string& fileName, const mode_t& mode)
200 {
201 return (chmod(fileName.c_str(), mode) == 0);
202 }
203
ChangeModeFile(const string & fileName,const mode_t & mode)204 bool ChangeModeFile(const string& fileName, const mode_t& mode)
205 {
206 if (access(fileName.c_str(), F_OK) != 0) {
207 return false;
208 }
209
210 return ChangeMode(fileName, mode);
211 }
212
ChangeModeDirectory(const std::string & path,const mode_t & mode)213 bool ChangeModeDirectory(const std::string& path, const mode_t& mode)
214 {
215 return OHOS::ChangeModeDirectory(path, mode);
216 }
217
PathToRealPath(const std::string & path,std::string & realPath)218 bool PathToRealPath(const std::string& path, std::string& realPath)
219 {
220 return OHOS::PathToRealPath(path, realPath);
221 }
222
Umask(const mode_t & mode)223 mode_t Umask(const mode_t& mode)
224 {
225 return umask(mode);
226 }
227
Open(const std::string & path,const int flags,const mode_t mode)228 int Open(const std::string& path, const int flags, const mode_t mode)
229 {
230 return open(path.c_str(), flags, mode);
231 }
232
CreateDirWithDefaultPerm(const std::string & path,uid_t aidRoot,uid_t aidSystem)233 void CreateDirWithDefaultPerm(const std::string& path, uid_t aidRoot, uid_t aidSystem)
234 {
235 FileUtil::ForceCreateDirectory(path);
236 chown(path.c_str(), aidRoot, aidSystem);
237 }
238
FormatPath2UnixStyle(std::string & path)239 void FormatPath2UnixStyle(std::string &path)
240 {
241 // unimplemented
242 }
243
RemoveFolderBeginWith(const std::string & path,const std::string & folderName)244 void RemoveFolderBeginWith(const std::string &path, const std::string &folderName)
245 {
246 // unimplemented
247 }
248
WriteBufferToFd(int fd,const char * buffer,size_t size)249 bool WriteBufferToFd(int fd, const char* buffer, size_t size)
250 {
251 if (fd < 0) {
252 return false;
253 }
254
255 if (buffer == nullptr) {
256 return false;
257 }
258
259 ssize_t writeSize = size;
260 if (writeSize != TEMP_FAILURE_RETRY(write(fd, buffer, size))) {
261 return false;
262 }
263
264 return true;
265 }
266
CreateFile(const std::string & path,mode_t mode)267 int CreateFile(const std::string &path, mode_t mode)
268 {
269 if (FileExists(path)) {
270 return 0;
271 } else {
272 std::ofstream fout(path);
273 if (!fout.is_open()) {
274 return -1;
275 }
276 fout.flush();
277 fout.close();
278 if (ChangeMode(path, mode) != 0) {
279 return -1;
280 }
281 }
282 return 0;
283 }
284
CopyFile(const std::string & src,const std::string & des)285 int CopyFile(const std::string &src, const std::string &des)
286 {
287 std::ifstream fin(src, ios::binary);
288 std::ofstream fout(des, ios::binary);
289 if (!fin.is_open()) {
290 return -1;
291 }
292 if (!fout.is_open()) {
293 return -1;
294 }
295 fout << fin.rdbuf();
296 if (fout.fail()) {
297 fout.clear();
298 }
299 fout.flush();
300 return 0;
301 }
302
IsDirectory(const std::string & path)303 bool IsDirectory(const std::string &path)
304 {
305 struct stat statBuffer;
306 if (stat(path.c_str(), &statBuffer) == 0 && S_ISDIR(statBuffer.st_mode)) {
307 return true;
308 }
309 return false;
310 }
311
GetLastLine(std::istream & fin,std::string & line,uint32_t maxLen)312 bool GetLastLine(std::istream &fin, std::string &line, uint32_t maxLen)
313 {
314 if (fin.tellg() <= 0) {
315 return false;
316 } else {
317 fin.seekg(-1, fin.cur);
318 }
319 uint32_t count = 0;
320 while (fin.good() && fin.peek() == fin.widen('\n') && fin.tellg() > 0 && count < maxLen) {
321 fin.seekg(-1, fin.cur);
322 count++;
323 }
324 if (!fin.good() || count >= maxLen) {
325 return false;
326 }
327 if (fin.tellg() == 0) {
328 return true;
329 }
330 count = 0;
331 while (fin.good() && fin.peek() != fin.widen('\n') && fin.tellg() > 0 && count < maxLen) {
332 fin.seekg(-1, fin.cur);
333 count++;
334 }
335 if (!fin.good() || count >= maxLen) {
336 return false;
337 }
338 if (fin.tellg() != 0) {
339 fin.seekg(1, fin.cur);
340 }
341 auto oldPos = fin.tellg();
342 getline(fin, line);
343 fin.seekg(oldPos);
344 return true;
345 }
346
GetFirstLine(const std::string & path)347 std::string GetFirstLine(const std::string& path)
348 {
349 std::ifstream inFile(path.c_str());
350 if (!inFile) {
351 return "";
352 }
353 std::string firstLine;
354 getline(inFile, firstLine);
355 inFile.close();
356 return firstLine;
357 }
358
GetParentDir(const std::string & path)359 std::string GetParentDir(const std::string &path)
360 {
361 string str = ExtractFilePath(path);
362 if (str.empty()) {
363 return "";
364 }
365 return str.substr(0, str.size() - 1);
366 }
367
IsLegalPath(const std::string & path)368 bool IsLegalPath(const std::string& path)
369 {
370 if (path.find("./") != std::string::npos ||
371 path.find("../") != std::string::npos) {
372 return false;
373 }
374 return true;
375 }
376
RenameFile(const std::string & src,const std::string & dest)377 bool RenameFile(const std::string& src, const std::string& dest)
378 {
379 if (std::rename(src.c_str(), dest.c_str()) == 0) {
380 return true;
381 }
382 return false;
383 }
384 } // namespace FileUtil
385 } // namespace HiviewDFX
386 } // namespace OHOS
387