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"
19 using namespace std;
20 namespace OHOS {
21 namespace HiviewDFX {
22 static const std::string UNKNOWN = "unknown";
FileUtils()23 FileUtils::FileUtils()
24 {
25 }
~FileUtils()26 FileUtils::~FileUtils()
27 {
28 }
29
CreateFolder(const string & path)30 bool 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
LoadStringFromProcCb(const std::string & path,bool oneLine,bool endWithoutN,const DataHandler & func)53 bool 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 return false;
58 }
59 auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(canonicalPath, "re"), fclose};
60 if (fp == nullptr) {
61 return false;
62 }
63 char *lineBuf = nullptr;
64 ssize_t lineLen;
65 size_t lineAlloc = 0;
66 while ((lineLen = getline(&lineBuf, &lineAlloc, fp.get())) > 0) {
67 lineBuf[lineLen] = '\0';
68 if (endWithoutN && lineBuf[lineLen-1] == '\n') {
69 lineBuf[lineLen-1] = '\0';
70 }
71 const string content = lineBuf;
72 func(content);
73 if (oneLine) {
74 break;
75 }
76 }
77 if (lineBuf != nullptr) {
78 free(lineBuf);
79 lineBuf = nullptr;
80 }
81 return true;
82 }
83
GetProcValue(const int32_t & pid,const string & path,const string & key)84 string FileUtils::GetProcValue(const int32_t &pid, const string& path, const string& key)
85 {
86 if (!DumpUtils::PathIsValid(path)) {
87 DUMPER_HILOGE(MODULE_COMMON, "path is valid");
88 return UNKNOWN;
89 }
90 auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "rd"), fclose};
91 if (fp == nullptr) {
92 DUMPER_HILOGE(MODULE_COMMON, "fopen failed");
93 return UNKNOWN;
94 }
95 char *lineBuf = nullptr;
96 ssize_t lineLen;
97 size_t lineAlloc = 0;
98 string content;
99 while ((lineLen = getline(&lineBuf, &lineAlloc, fp.get())) > 0) {
100 lineBuf[lineLen] = '\0';
101 if (lineBuf[lineLen - 1] == '\n') {
102 lineBuf[lineLen - 1] = '\0';
103 }
104 content = lineBuf;
105 if (content.find(key) != std::string::npos) {
106 break;
107 }
108 content = "";
109 }
110 if (lineBuf != nullptr) {
111 free(lineBuf);
112 lineBuf = nullptr;
113 }
114 if (!content.empty()) {
115 vector<string> values;
116 StringUtils::GetInstance().StringSplit(content, ":", values);
117 if (values.empty()) {
118 DUMPER_HILOGE(MODULE_SERVICE, "values is empty");
119 return UNKNOWN;
120 } else {
121 return values[1].substr(1);
122 }
123 } else {
124 DUMPER_HILOGE(MODULE_SERVICE, "content is empty");
125 return UNKNOWN;
126 }
127 }
128 } // namespace HiviewDFX
129 } // namespace OHOS