1 /*
2 * Copyright (c) 2024 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 "hidebug_util.h"
17
18 #include <cstring>
19 #include <ctime>
20 #include <fcntl.h>
21 #include <thread>
22 #include <vector>
23
24 #include <sys/stat.h>
25 #include <sys/xattr.h>
26 #include <unistd.h>
27
28 #include "application_context.h"
29 #include "parameters.h"
30
31 #include "hilog/log.h"
32
33 namespace OHOS {
34 namespace HiviewDFX {
35 namespace {
36
37 #undef LOG_DOMAIN
38 #define LOG_DOMAIN 0xD002D0A
39 #undef LOG_TAG
40 #define LOG_TAG "CommonUtil"
41
GetNanoSecondsTimestamp(clockid_t clockId)42 int64_t GetNanoSecondsTimestamp(clockid_t clockId)
43 {
44 struct timespec times{};
45 if (clock_gettime(clockId, ×) == -1) {
46 return -1;
47 }
48 constexpr int64_t secondToNanosecond = 1 * 1000 * 1000 * 1000;
49 return times.tv_sec * secondToNanosecond + times.tv_nsec;
50 }
51 }
52
GetElapsedNanoSecondsSinceBoot()53 int64_t GetElapsedNanoSecondsSinceBoot()
54 {
55 return GetNanoSecondsTimestamp(CLOCK_BOOTTIME);
56 }
57
GetRealNanoSecondsTimestamp()58 int64_t GetRealNanoSecondsTimestamp()
59 {
60 return GetNanoSecondsTimestamp(CLOCK_REALTIME);
61 }
62
GetProcessDir(DirectoryType type)63 std::string GetProcessDir(DirectoryType type)
64 {
65 auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
66 if (!context) {
67 return "";
68 }
69 switch (type) {
70 case DirectoryType::CACHE:
71 return context->GetCacheDir();
72 case DirectoryType::FILE:
73 return context->GetFilesDir();
74 default:
75 return "";
76 }
77 }
78
SplitStr(const std::string & origin,char delimiter,const std::function<bool (std::string &)> & filter)79 std::vector<std::string> SplitStr(const std::string& origin, char delimiter,
80 const std::function<bool(std::string&)>& filter)
81 {
82 std::vector<std::string> tokens;
83 size_t index = 0;
84 for (size_t i = 0; i <= origin.length(); ++i) {
85 if (i == origin.length() || origin[i] == delimiter) {
86 std::string token = origin.substr(index, i - index);
87 if (!filter || filter(token)) {
88 tokens.emplace_back(std::move(token));
89 }
90 index = i + 1;
91 }
92 }
93 return tokens;
94 }
95
GetXAttr(const std::string & fileName,const std::string & key,std::string & value,size_t maxLength)96 bool GetXAttr(const std::string& fileName, const std::string& key, std::string& value, size_t maxLength)
97 {
98 std::string readValue = std::string(maxLength + 1, '\0');
99 if (getxattr(fileName.c_str(), key.c_str(), readValue.data(), maxLength) == -1) {
100 HILOG_ERROR(LOG_CORE, "failed to getxattr %{public}s from %{public}s because of %{public}s.",
101 key.c_str(), fileName.c_str(), strerror(errno));
102 return false;
103 }
104 value = readValue.c_str();
105 return true;
106 }
107
SetXAttr(const std::string & fileName,const std::string & key,const std::string & value)108 bool SetXAttr(const std::string& fileName, const std::string& key, const std::string& value)
109 {
110 if (setxattr(fileName.c_str(), key.c_str(), value.c_str(), value.size(), 0) != 0) {
111 HILOG_ERROR(LOG_CORE, "failed to setxattr %{public}s to %{public}s because of %{public}s.",
112 key.c_str(), fileName.c_str(), strerror(errno));
113 return false;
114 }
115 return true;
116 }
117
IsLegalPath(const std::string & path)118 bool IsLegalPath(const std::string& path)
119 {
120 return !path.empty() && path.find("./") == std::string::npos;
121 }
122
GetFileSize(const std::string & path)123 uint64_t GetFileSize(const std::string& path)
124 {
125 struct stat statBuf{};
126 if (stat(path.c_str(), &statBuf) == 0) {
127 return statBuf.st_size;
128 }
129 return 0;
130 }
131
CreateFile(const std::string & path)132 bool CreateFile(const std::string &path)
133 {
134 if (access(path.c_str(), F_OK) == 0) {
135 return access(path.c_str(), W_OK) == 0;
136 }
137 const mode_t defaultMode = S_IRUSR | S_IWUSR | S_IRGRP; // -rw-r-----
138 int fd = creat(path.c_str(), defaultMode);
139 if (fd == -1) {
140 HILOG_ERROR(LOG_CORE, "file create failed, errno = %{public}d", errno);
141 return false;
142 }
143 close(fd);
144 return true;
145 }
146
CreateDirectory(const std::string & path,unsigned mode)147 bool CreateDirectory(const std::string &path, unsigned mode)
148 {
149 std::vector<std::string> subPaths = SplitStr(path, '/', [](std::string& subPath) {
150 return !subPath.empty();
151 });
152 std::string currentPath;
153 for (const auto& subPath : subPaths) {
154 currentPath += "/" + subPath;
155 if (mkdir(currentPath.c_str(), mode) != 0 && errno != EEXIST) {
156 HILOG_ERROR(LOG_CORE, "directory %{public}s create failed, errno = %{public}d", currentPath.c_str(), errno);
157 return false;
158 }
159 }
160 return true;
161 }
162
OpenFile(const std::string & path,const std::string & mode)163 std::unique_ptr<SmartFile> SmartFile::OpenFile(const std::string& path, const std::string& mode)
164 {
165 if (!IsLegalPath(path)) {
166 HILOG_ERROR(LOG_CORE, "illegal file path %{public}s .", path.c_str());
167 return nullptr;
168 }
169 auto file = fopen(path.c_str(), mode.c_str());
170 if (file == nullptr) {
171 HILOG_ERROR(LOG_CORE, "can not open file %{public}s for %{public}s because of %{public}s.", path.c_str(),
172 mode.c_str(), strerror(errno));
173 return nullptr;
174 }
175 return std::unique_ptr<SmartFile>(new (std::nothrow) SmartFile(file));
176 }
177
~SmartFile()178 SmartFile::~SmartFile()
179 {
180 if (fclose(file_) != 0) {
181 HILOG_ERROR(LOG_CORE, "failed close file because of %{public}s.", strerror(errno));
182 }
183 }
184
Write(const void * __restrict dataPtr,size_t itemSize,size_t dataNum)185 bool SmartFile::Write(const void *__restrict dataPtr, size_t itemSize, size_t dataNum)
186 {
187 errno = 0;
188 if (fwrite(dataPtr, itemSize, dataNum, file_) != dataNum) {
189 HILOG_ERROR(LOG_CORE, "failed to write file because of %{public}s.", strerror(errno));
190 return false;
191 }
192 return true;
193 }
194
Read(void * __restrict dataPtr,size_t itemSize,size_t dataNum)195 size_t SmartFile::Read(void *__restrict dataPtr, size_t itemSize, size_t dataNum)
196 {
197 return fread(dataPtr, itemSize, dataNum, file_);
198 }
199
IsBetaVersion()200 bool IsBetaVersion()
201 {
202 return OHOS::system::GetParameter("const.logsystem.versiontype", "") == "beta";
203 }
204
IsDebuggableHap()205 bool IsDebuggableHap()
206 {
207 const char* debuggableEnv = getenv("HAP_DEBUGGABLE");
208 return debuggableEnv != nullptr && strcmp(debuggableEnv, "true") == 0;
209 }
210
IsDeveloperOptionsEnabled()211 bool IsDeveloperOptionsEnabled()
212 {
213 return OHOS::system::GetBoolParameter("const.security.developermode.state", false);
214 }
215 }
216 }
217