• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &times) == -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