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