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#include <unistd.h> 16#include <sys/stat.h> 17#include "hilog_wrapper.h" 18#include "util/file_utils.h" 19using namespace std; 20namespace OHOS { 21namespace HiviewDFX { 22static const std::string UNKNOWN = "unknown"; 23FileUtils::FileUtils() 24{ 25} 26FileUtils::~FileUtils() 27{ 28} 29 30bool FileUtils::CreateFolder(const string &path) 31{ 32 if (!access(path.c_str(), F_OK) || path == "") { 33 return true; 34 } 35 36 size_t pos = path.rfind("/"); 37 if (pos == string::npos) { 38 return false; 39 } 40 41 string upperPath = path.substr(0, pos); 42 if (CreateFolder(upperPath)) { 43 if (mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO)) { 44 if (errno != EEXIST) { 45 return false; 46 } 47 } 48 return true; 49 } 50 return false; 51} 52 53bool FileUtils::LoadStringFromProcCb(const std::string& path, bool oneLine, bool endWithoutN, const DataHandler& func) 54{ 55 char canonicalPath[PATH_MAX] = {0}; 56 if (realpath(path.c_str(), canonicalPath) == nullptr) { 57 DUMPER_HILOGE(MODULE_COMMON, "realpath failed, errno=%{public}d, path=%{public}s", errno, path.c_str()); 58 return false; 59 } 60 auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(canonicalPath, "re"), fclose}; 61 if (fp == nullptr) { 62 DUMPER_HILOGE(MODULE_COMMON, "fopen failed, errno=%{public}d, path=%{public}s", errno, path.c_str()); 63 return false; 64 } 65 char *lineBuf = nullptr; 66 ssize_t lineLen; 67 size_t lineAlloc = 0; 68 while ((lineLen = getline(&lineBuf, &lineAlloc, fp.get())) > 0) { 69 lineBuf[lineLen] = '\0'; 70 if (endWithoutN && lineBuf[lineLen-1] == '\n') { 71 lineBuf[lineLen-1] = '\0'; 72 } 73 const string content = lineBuf; 74 func(content); 75 if (oneLine) { 76 break; 77 } 78 } 79 if (lineBuf != nullptr) { 80 free(lineBuf); 81 lineBuf = nullptr; 82 } 83 return true; 84} 85 86string FileUtils::GetProcValue(const int32_t &pid, const string& path, const string& key) 87{ 88 if (!DumpUtils::PathIsValid(path)) { 89 DUMPER_HILOGE(MODULE_COMMON, "path is valid"); 90 return UNKNOWN; 91 } 92 auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "rd"), fclose}; 93 if (fp == nullptr) { 94 DUMPER_HILOGE(MODULE_COMMON, "fopen failed"); 95 return UNKNOWN; 96 } 97 char *lineBuf = nullptr; 98 ssize_t lineLen; 99 size_t lineAlloc = 0; 100 string content; 101 while ((lineLen = getline(&lineBuf, &lineAlloc, fp.get())) > 0) { 102 lineBuf[lineLen] = '\0'; 103 if (lineBuf[lineLen - 1] == '\n') { 104 lineBuf[lineLen - 1] = '\0'; 105 } 106 content = lineBuf; 107 if (content.find(key) != std::string::npos) { 108 break; 109 } 110 content = ""; 111 } 112 if (lineBuf != nullptr) { 113 free(lineBuf); 114 lineBuf = nullptr; 115 } 116 if (!content.empty()) { 117 vector<string> values; 118 StringUtils::GetInstance().StringSplit(content, ":", values); 119 if (values.empty()) { 120 DUMPER_HILOGE(MODULE_SERVICE, "values is empty"); 121 return UNKNOWN; 122 } else { 123 return values[1].substr(1); 124 } 125 } else { 126 DUMPER_HILOGE(MODULE_SERVICE, "content is empty"); 127 return UNKNOWN; 128 } 129} 130} // namespace HiviewDFX 131} // namespace OHOS