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