• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "dfx_util.h"
17 
18 #include <cctype>
19 #include <climits>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <cstring>
23 #include <ctime>
24 #include <securec.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <sys/time.h>
28 #include <fcntl.h>
29 #include <pthread.h>
30 #include <unistd.h>
31 #include <dirent.h>
32 #include "dfx_define.h"
33 #include "dfx_log.h"
34 
35 #ifdef LOG_DOMAIN
36 #undef LOG_DOMAIN
37 #define LOG_DOMAIN 0xD002D11
38 #endif
39 
40 #ifdef LOG_TAG
41 #undef LOG_TAG
42 #define LOG_TAG "DfxUtil"
43 #endif
44 
45 namespace OHOS {
46 namespace HiviewDFX {
TrimAndDupStr(const std::string & source,std::string & str)47 bool TrimAndDupStr(const std::string &source, std::string &str)
48 {
49     if (source.empty()) {
50         return false;
51     }
52 
53     const char *begin = source.data();
54     const char *end = begin + source.size();
55     if (begin == end) {
56         DFXLOG_ERROR("Source is empty");
57         return false;
58     }
59 
60     while ((begin < end) && isspace(*begin)) {
61         begin++;
62     }
63 
64     while ((begin < end) && isspace(*(end - 1))) {
65         end--;
66     }
67 
68     if (begin == end) {
69         return false;
70     }
71 
72     uint32_t maxStrLen = NAME_LEN;
73     uint32_t offset = static_cast<uint32_t>(end - begin);
74     if (maxStrLen > offset) {
75         maxStrLen = offset;
76     }
77 
78     str.assign(begin, maxStrLen);
79     return true;
80 }
81 
GetTimeMilliSeconds(void)82 uint64_t GetTimeMilliSeconds(void)
83 {
84     struct timespec ts;
85     (void)clock_gettime(CLOCK_REALTIME, &ts);
86     return ((uint64_t)ts.tv_sec * NUMBER_ONE_THOUSAND) + // 1000 : second to millisecond convert ratio
87         (((uint64_t)ts.tv_nsec) / NUMBER_ONE_MILLION); // 1000000 : nanosecond to millisecond convert ratio
88 }
89 
GetCurrentTimeStr(uint64_t current)90 std::string GetCurrentTimeStr(uint64_t current)
91 {
92     time_t now = time(nullptr);
93     uint64_t millsecond = 0;
94     const uint64_t ratio = NUMBER_ONE_THOUSAND;
95     if (current > static_cast<uint64_t>(now)) {
96         millsecond = current % ratio;
97         now = static_cast<time_t>(current / ratio);
98     }
99 
100     auto tm = std::localtime(&now);
101     char seconds[128] = {0}; // 128 : time buffer size
102     if (tm == nullptr || strftime(seconds, sizeof(seconds) - 1, "%Y-%m-%d %H:%M:%S", tm) == 0) {
103         return "invalid timestamp\n";
104     }
105 
106     char millBuf[256] = {0}; // 256 : milliseconds buffer size
107     int ret = snprintf_s(millBuf, sizeof(millBuf), sizeof(millBuf) - 1,
108         "%s.%03u\n", seconds, millsecond);
109     if (ret <= 0) {
110         return "invalid timestamp\n";
111     }
112     return std::string(millBuf, strlen(millBuf));
113 }
114 
ReadDirFiles(const std::string & path,std::vector<std::string> & files)115 bool ReadDirFiles(const std::string& path, std::vector<std::string>& files)
116 {
117     DIR *dir = opendir(path.c_str());
118     if (dir == nullptr) {
119         return false;
120     }
121 
122     struct dirent *ent;
123     while ((ent = readdir(dir)) != nullptr) {
124         // current dir OR parent dir
125         if ((strcmp(ent->d_name, ".") == 0) || (strcmp(ent->d_name, "..") == 0)) {
126             continue;
127         }
128         files.emplace_back(std::string(ent->d_name));
129     }
130     (void)closedir(dir);
131     return (files.size() > 0);
132 }
133 
ReadDirFilesByPid(const int & pid,std::vector<std::string> & files)134 bool ReadDirFilesByPid(const int& pid, std::vector<std::string>& files)
135 {
136     char path[PATH_LEN] = {0};
137     if (pid == getpid()) {
138         if (snprintf_s(path, sizeof(path), sizeof(path) - 1, PROC_SELF_TASK_PATH) <= 0) {
139             return false;
140         }
141     } else {
142         if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "/proc/%d/task", pid) <= 0) {
143             return false;
144         }
145     }
146 
147     char realPath[PATH_MAX];
148     if (!realpath(path, realPath)) {
149         return false;
150     }
151     return ReadDirFiles(realPath, files);
152 }
153 
VerifyFilePath(const std::string & filePath,const std::vector<const std::string> & validPaths)154 bool VerifyFilePath(const std::string& filePath, const std::vector<const std::string>& validPaths)
155 {
156     if (validPaths.size() == 0) {
157         return true;
158     }
159 
160     for (auto validPath : validPaths) {
161         if (filePath.find(validPath) == 0) {
162             return true;
163         }
164     }
165     return false;
166 }
167 
GetFileSize(const int & fd)168 off_t GetFileSize(const int& fd)
169 {
170     off_t fileSize = 0;
171     if (fd >= 0) {
172         struct stat fileStat;
173         if (fstat(fd, &fileStat) == 0) {
174             fileSize = fileStat.st_size;
175         }
176     }
177     return fileSize;
178 }
179 
GetStackRange(uintptr_t & stackBottom,uintptr_t & stackTop)180 int GetStackRange(uintptr_t& stackBottom, uintptr_t& stackTop)
181 {
182     pthread_attr_t tattr;
183     void *base = nullptr;
184     size_t size = 0;
185     pthread_getattr_np(pthread_self(), &tattr);
186     int ret = pthread_attr_getstack(&tattr, &base, &size);
187     stackBottom = reinterpret_cast<uintptr_t>(base);
188     stackTop = reinterpret_cast<uintptr_t>(base) + size;
189     return ret;
190 }
191 }   // namespace HiviewDFX
192 }   // namespace OHOS
193