17405867cSopenharmony_ci/* 27405867cSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 37405867cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 47405867cSopenharmony_ci * you may not use this file except in compliance with the License. 57405867cSopenharmony_ci * You may obtain a copy of the License at 67405867cSopenharmony_ci * 77405867cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 87405867cSopenharmony_ci * 97405867cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 107405867cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 117405867cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127405867cSopenharmony_ci * See the License for the specific language governing permissions and 137405867cSopenharmony_ci * limitations under the License. 147405867cSopenharmony_ci */ 157405867cSopenharmony_ci#include "file_util.h" 167405867cSopenharmony_ci 177405867cSopenharmony_ci#include <dirent.h> 187405867cSopenharmony_ci#include <fstream> 197405867cSopenharmony_ci#include <iostream> 207405867cSopenharmony_ci#include <sys/stat.h> 217405867cSopenharmony_ci#include <sys/types.h> 227405867cSopenharmony_ci#include <sys/xattr.h> 237405867cSopenharmony_ci#include <unistd.h> 247405867cSopenharmony_ci 257405867cSopenharmony_cinamespace OHOS { 267405867cSopenharmony_cinamespace HiviewDFX { 277405867cSopenharmony_cinamespace FileUtil { 287405867cSopenharmony_cinamespace { 297405867cSopenharmony_ciconst char PATH_DELIMITER = '/'; 307405867cSopenharmony_ciconstexpr mode_t FILE_PERM_600 = S_IRUSR | S_IWUSR; 317405867cSopenharmony_ci} 327405867cSopenharmony_cibool IsFileExists(const std::string& file) 337405867cSopenharmony_ci{ 347405867cSopenharmony_ci return access(file.c_str(), F_OK) == 0; 357405867cSopenharmony_ci} 367405867cSopenharmony_ci 377405867cSopenharmony_cibool IsFile(const std::string& file) 387405867cSopenharmony_ci{ 397405867cSopenharmony_ci struct stat statBuf {}; 407405867cSopenharmony_ci return lstat(file.c_str(), &statBuf) == 0 ? S_ISREG(statBuf.st_mode) : false; 417405867cSopenharmony_ci} 427405867cSopenharmony_ci 437405867cSopenharmony_cibool IsDirectory(const std::string& dir) 447405867cSopenharmony_ci{ 457405867cSopenharmony_ci struct stat statBuf {}; 467405867cSopenharmony_ci return lstat(dir.c_str(), &statBuf) == 0 ? S_ISDIR(statBuf.st_mode) : false; 477405867cSopenharmony_ci} 487405867cSopenharmony_ci 497405867cSopenharmony_cibool RemoveFile(const std::string& file) 507405867cSopenharmony_ci{ 517405867cSopenharmony_ci return !IsFileExists(file) || (remove(file.c_str()) == 0); 527405867cSopenharmony_ci} 537405867cSopenharmony_ci 547405867cSopenharmony_cibool RemoveDirectory(const std::string& dir) 557405867cSopenharmony_ci{ 567405867cSopenharmony_ci return !IsFileExists(dir) || (rmdir(dir.c_str()) == 0); 577405867cSopenharmony_ci} 587405867cSopenharmony_ci 597405867cSopenharmony_cibool ForceCreateDirectory(const std::string& dir) 607405867cSopenharmony_ci{ 617405867cSopenharmony_ci std::string::size_type index = 0; 627405867cSopenharmony_ci do { 637405867cSopenharmony_ci std::string subPath; 647405867cSopenharmony_ci index = dir.find('/', index + 1); // (index + 1) means the next char traversed 657405867cSopenharmony_ci if (index == std::string::npos) { 667405867cSopenharmony_ci subPath = dir; 677405867cSopenharmony_ci } else { 687405867cSopenharmony_ci subPath = dir.substr(0, index); 697405867cSopenharmony_ci } 707405867cSopenharmony_ci 717405867cSopenharmony_ci if (!IsFileExists(subPath) && mkdir(subPath.c_str(), S_IRWXU) != 0) { 727405867cSopenharmony_ci return false; 737405867cSopenharmony_ci } 747405867cSopenharmony_ci } while (index != std::string::npos); 757405867cSopenharmony_ci return IsFileExists(dir); 767405867cSopenharmony_ci} 777405867cSopenharmony_ci 787405867cSopenharmony_cibool ForceRemoveDirectory(const std::string& dir, bool isDeleteSelf) 797405867cSopenharmony_ci{ 807405867cSopenharmony_ci if (IsFile(dir)) { 817405867cSopenharmony_ci return RemoveFile(dir); 827405867cSopenharmony_ci } else if (IsDirectory(dir)) { 837405867cSopenharmony_ci DIR* dirPtr = opendir(dir.c_str()); 847405867cSopenharmony_ci if (dirPtr == nullptr) { 857405867cSopenharmony_ci return false; 867405867cSopenharmony_ci } 877405867cSopenharmony_ci struct dirent* dirInfo = nullptr; 887405867cSopenharmony_ci while ((dirInfo = readdir(dirPtr)) != nullptr) { 897405867cSopenharmony_ci // do not process the special dir 907405867cSopenharmony_ci if (strcmp(dirInfo->d_name, ".") == 0 || strcmp(dirInfo->d_name, "..") == 0) { 917405867cSopenharmony_ci continue; 927405867cSopenharmony_ci } 937405867cSopenharmony_ci std::string filePath = GetFilePathByDir(dir, dirInfo->d_name); 947405867cSopenharmony_ci if (!ForceRemoveDirectory(filePath)) { 957405867cSopenharmony_ci closedir(dirPtr); 967405867cSopenharmony_ci return false; 977405867cSopenharmony_ci } 987405867cSopenharmony_ci } 997405867cSopenharmony_ci closedir(dirPtr); 1007405867cSopenharmony_ci if (isDeleteSelf && !RemoveDirectory(dir)) { 1017405867cSopenharmony_ci return false; 1027405867cSopenharmony_ci } 1037405867cSopenharmony_ci } else { 1047405867cSopenharmony_ci return false; 1057405867cSopenharmony_ci } 1067405867cSopenharmony_ci return true; 1077405867cSopenharmony_ci} 1087405867cSopenharmony_ci 1097405867cSopenharmony_civoid GetDirFiles(const std::string& dir, std::vector<std::string>& files) 1107405867cSopenharmony_ci{ 1117405867cSopenharmony_ci DIR* dirPtr = opendir(dir.c_str()); 1127405867cSopenharmony_ci if (dirPtr == nullptr) { 1137405867cSopenharmony_ci return; 1147405867cSopenharmony_ci } 1157405867cSopenharmony_ci 1167405867cSopenharmony_ci struct dirent* ent = nullptr; 1177405867cSopenharmony_ci while ((ent = readdir(dirPtr)) != nullptr) { 1187405867cSopenharmony_ci if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { 1197405867cSopenharmony_ci continue; 1207405867cSopenharmony_ci } 1217405867cSopenharmony_ci std::string filePath = GetFilePathByDir(dir, ent->d_name); 1227405867cSopenharmony_ci if (IsFile(filePath)) { // do not process subdirectory 1237405867cSopenharmony_ci files.push_back(filePath); 1247405867cSopenharmony_ci } 1257405867cSopenharmony_ci } 1267405867cSopenharmony_ci closedir(dirPtr); 1277405867cSopenharmony_ci} 1287405867cSopenharmony_ci 1297405867cSopenharmony_ciuint64_t GetDirSize(const std::string& dir) 1307405867cSopenharmony_ci{ 1317405867cSopenharmony_ci std::vector<std::string> files; 1327405867cSopenharmony_ci GetDirFiles(dir, files); 1337405867cSopenharmony_ci uint64_t totalSize = 0; 1347405867cSopenharmony_ci struct stat statBuf {}; 1357405867cSopenharmony_ci for (auto& file : files) { 1367405867cSopenharmony_ci if (stat(file.c_str(), &statBuf) == 0) { 1377405867cSopenharmony_ci totalSize += static_cast<uint64_t>(statBuf.st_size); 1387405867cSopenharmony_ci } 1397405867cSopenharmony_ci } 1407405867cSopenharmony_ci return totalSize; 1417405867cSopenharmony_ci} 1427405867cSopenharmony_ci 1437405867cSopenharmony_ciuint64_t GetFileSize(const std::string& file) 1447405867cSopenharmony_ci{ 1457405867cSopenharmony_ci struct stat statBuf {}; 1467405867cSopenharmony_ci return stat(file.c_str(), &statBuf) == 0 ? static_cast<uint64_t>(statBuf.st_size) : 0; 1477405867cSopenharmony_ci} 1487405867cSopenharmony_ci 1497405867cSopenharmony_cibool ChangeMode(const std::string& file, const mode_t& mode) 1507405867cSopenharmony_ci{ 1517405867cSopenharmony_ci return (chmod(file.c_str(), mode) == 0); 1527405867cSopenharmony_ci} 1537405867cSopenharmony_ci 1547405867cSopenharmony_cibool CreateFile(const std::string& file, const mode_t& mode) 1557405867cSopenharmony_ci{ 1567405867cSopenharmony_ci if (IsFileExists(file)) { 1577405867cSopenharmony_ci return true; 1587405867cSopenharmony_ci } 1597405867cSopenharmony_ci std::ofstream fout(file); 1607405867cSopenharmony_ci if (!fout.is_open()) { 1617405867cSopenharmony_ci return false; 1627405867cSopenharmony_ci } 1637405867cSopenharmony_ci fout.flush(); 1647405867cSopenharmony_ci fout.close(); 1657405867cSopenharmony_ci return ChangeMode(file, mode); 1667405867cSopenharmony_ci} 1677405867cSopenharmony_ci 1687405867cSopenharmony_cibool SaveStringToFile(const std::string& file, const std::string& content, bool isTrunc) 1697405867cSopenharmony_ci{ 1707405867cSopenharmony_ci if (content.empty()) { 1717405867cSopenharmony_ci return true; 1727405867cSopenharmony_ci } 1737405867cSopenharmony_ci 1747405867cSopenharmony_ci if (!CreateFile(file, FILE_PERM_600)) { 1757405867cSopenharmony_ci return false; 1767405867cSopenharmony_ci } 1777405867cSopenharmony_ci std::ofstream os; 1787405867cSopenharmony_ci if (isTrunc) { 1797405867cSopenharmony_ci os.open(file.c_str(), std::ios::out | std::ios::trunc); 1807405867cSopenharmony_ci } else { 1817405867cSopenharmony_ci os.open(file.c_str(), std::ios::out | std::ios::app); 1827405867cSopenharmony_ci } 1837405867cSopenharmony_ci if (!os.is_open()) { 1847405867cSopenharmony_ci return false; 1857405867cSopenharmony_ci } 1867405867cSopenharmony_ci 1877405867cSopenharmony_ci os.write(content.c_str(), content.length()); 1887405867cSopenharmony_ci if (os.fail()) { 1897405867cSopenharmony_ci os.close(); 1907405867cSopenharmony_ci return false; 1917405867cSopenharmony_ci } 1927405867cSopenharmony_ci os.close(); 1937405867cSopenharmony_ci return true; 1947405867cSopenharmony_ci} 1957405867cSopenharmony_ci 1967405867cSopenharmony_cistd::string GetFilePathByDir(const std::string& dir, const std::string& fileName) 1977405867cSopenharmony_ci{ 1987405867cSopenharmony_ci if (dir.empty()) { 1997405867cSopenharmony_ci return fileName; 2007405867cSopenharmony_ci } 2017405867cSopenharmony_ci std::string filePath = dir; 2027405867cSopenharmony_ci if (filePath.back() != '/') { 2037405867cSopenharmony_ci filePath.push_back(PATH_DELIMITER); 2047405867cSopenharmony_ci } 2057405867cSopenharmony_ci filePath.append(fileName); 2067405867cSopenharmony_ci return filePath; 2077405867cSopenharmony_ci} 2087405867cSopenharmony_ci 2097405867cSopenharmony_cibool LoadLinesFromFile(const std::string& filePath, std::vector<std::string>& lines) 2107405867cSopenharmony_ci{ 2117405867cSopenharmony_ci std::ifstream file(filePath); 2127405867cSopenharmony_ci if (file.is_open()) { 2137405867cSopenharmony_ci std::string line; 2147405867cSopenharmony_ci while (std::getline(file, line)) { 2157405867cSopenharmony_ci lines.emplace_back(line); 2167405867cSopenharmony_ci } 2177405867cSopenharmony_ci file.close(); 2187405867cSopenharmony_ci return true; 2197405867cSopenharmony_ci } 2207405867cSopenharmony_ci return false; 2217405867cSopenharmony_ci} 2227405867cSopenharmony_ci 2237405867cSopenharmony_cibool SetDirXattr(const std::string& dir, const std::string& name, const std::string& value) 2247405867cSopenharmony_ci{ 2257405867cSopenharmony_ci return setxattr(dir.c_str(), name.c_str(), value.c_str(), strlen(value.c_str()), 0) == 0; 2267405867cSopenharmony_ci} 2277405867cSopenharmony_ci} // namespace FileUtil 2287405867cSopenharmony_ci} // namespace HiviewDFX 2297405867cSopenharmony_ci} // namespace OHOS 230