12498b56bSopenharmony_ci/* 22498b56bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 32498b56bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 42498b56bSopenharmony_ci * you may not use this file except in compliance with the License. 52498b56bSopenharmony_ci * You may obtain a copy of the License at 62498b56bSopenharmony_ci * 72498b56bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 82498b56bSopenharmony_ci * 92498b56bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 102498b56bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 112498b56bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 122498b56bSopenharmony_ci * See the License for the specific language governing permissions and 132498b56bSopenharmony_ci * limitations under the License. 142498b56bSopenharmony_ci */ 152498b56bSopenharmony_ci#include <codecvt> 162498b56bSopenharmony_ci#include <cstdint> 172498b56bSopenharmony_ci#include <cstdlib> 182498b56bSopenharmony_ci#include <chrono> 192498b56bSopenharmony_ci#include <functional> 202498b56bSopenharmony_ci#include <regex> 212498b56bSopenharmony_ci#include <sstream> 222498b56bSopenharmony_ci#include <thread> 232498b56bSopenharmony_ci#include <fstream> 242498b56bSopenharmony_ci#include <fcntl.h> 252498b56bSopenharmony_ci#include <securec.h> 262498b56bSopenharmony_ci#include <hilog/log.h> 272498b56bSopenharmony_ci#include <unistd.h> 282498b56bSopenharmony_ci#include "hilog_common.h" 292498b56bSopenharmony_ci#include "hilog_cmd.h" 302498b56bSopenharmony_ci#include "log_utils.h" 312498b56bSopenharmony_ci 322498b56bSopenharmony_cinamespace { 332498b56bSopenharmony_ci constexpr uint32_t ONE_KB = (1UL << 10); 342498b56bSopenharmony_ci constexpr uint32_t ONE_MB = (1UL << 20); 352498b56bSopenharmony_ci constexpr uint32_t ONE_GB = (1UL << 30); 362498b56bSopenharmony_ci constexpr uint64_t ONE_TB = (1ULL << 40); 372498b56bSopenharmony_ci constexpr uint32_t DOMAIN_MIN = DOMAIN_APP_MIN; 382498b56bSopenharmony_ci constexpr uint32_t DOMAIN_MAX = DOMAIN_OS_MAX; 392498b56bSopenharmony_ci constexpr int CMDLINE_PATH_LEN = 32; 402498b56bSopenharmony_ci constexpr int CMDLINE_LEN = 128; 412498b56bSopenharmony_ci constexpr int STATUS_PATH_LEN = 32; 422498b56bSopenharmony_ci constexpr int STATUS_LEN = 1024; 432498b56bSopenharmony_ci const std::string SH_NAMES[] = { "sh", "/bin/sh", "/system/bin/sh", "/xbin/sh", "/system/xbin/sh"}; 442498b56bSopenharmony_ci} 452498b56bSopenharmony_ci 462498b56bSopenharmony_cinamespace OHOS { 472498b56bSopenharmony_cinamespace HiviewDFX { 482498b56bSopenharmony_ciusing namespace std; 492498b56bSopenharmony_ciusing namespace std::chrono; 502498b56bSopenharmony_ci 512498b56bSopenharmony_ci// Buffer Size&Char Map 522498b56bSopenharmony_cistatic const KVMap<char, uint64_t> g_SizeMap({ 532498b56bSopenharmony_ci {'B', 1}, {'K', ONE_KB}, {'M', ONE_MB}, 542498b56bSopenharmony_ci {'G', ONE_GB}, {'T', ONE_TB} 552498b56bSopenharmony_ci}, ' ', 0); 562498b56bSopenharmony_ci 572498b56bSopenharmony_cistring Size2Str(uint64_t size) 582498b56bSopenharmony_ci{ 592498b56bSopenharmony_ci string str; 602498b56bSopenharmony_ci uint64_t unit = 1; 612498b56bSopenharmony_ci switch (size) { 622498b56bSopenharmony_ci case 0 ... ONE_KB - 1: unit = 1; break; 632498b56bSopenharmony_ci case ONE_KB ... ONE_MB - 1: unit = ONE_KB; break; 642498b56bSopenharmony_ci case ONE_MB ... ONE_GB - 1: unit = ONE_MB; break; 652498b56bSopenharmony_ci case ONE_GB ... ONE_TB - 1: unit = ONE_GB; break; 662498b56bSopenharmony_ci default: unit = ONE_TB; break; 672498b56bSopenharmony_ci } 682498b56bSopenharmony_ci float i = (static_cast<float>(size)) / unit; 692498b56bSopenharmony_ci constexpr int len = 16; 702498b56bSopenharmony_ci char buf[len] = { 0 }; 712498b56bSopenharmony_ci int ret = snprintf_s(buf, len, len - 1, "%.1f", i); 722498b56bSopenharmony_ci if (ret <= 0) { 732498b56bSopenharmony_ci str = to_string(size); 742498b56bSopenharmony_ci } else { 752498b56bSopenharmony_ci str = buf; 762498b56bSopenharmony_ci } 772498b56bSopenharmony_ci return str + g_SizeMap.GetKey(unit); 782498b56bSopenharmony_ci} 792498b56bSopenharmony_ci 802498b56bSopenharmony_ciuint64_t Str2Size(const string& str) 812498b56bSopenharmony_ci{ 822498b56bSopenharmony_ci std::regex reg("[0-9]+[BKMGT]?"); 832498b56bSopenharmony_ci if (!std::regex_match(str, reg)) { 842498b56bSopenharmony_ci return 0; 852498b56bSopenharmony_ci } 862498b56bSopenharmony_ci uint64_t index = str.size() - 1; 872498b56bSopenharmony_ci uint64_t unit = g_SizeMap.GetValue(str[index]); 882498b56bSopenharmony_ci 892498b56bSopenharmony_ci uint64_t value = stoull(str.substr(0, unit !=0 ? index : index + 1)); 902498b56bSopenharmony_ci return value * (unit != 0 ? unit : 1); 912498b56bSopenharmony_ci} 922498b56bSopenharmony_ci 932498b56bSopenharmony_ci// Error Codes&Strings Map 942498b56bSopenharmony_cistatic const KVMap<int16_t, string> g_ErrorMsgs({ 952498b56bSopenharmony_ci {RET_SUCCESS, "Success"}, 962498b56bSopenharmony_ci {RET_FAIL, "Unknown failure reason"}, 972498b56bSopenharmony_ci {ERR_LOG_LEVEL_INVALID, "Invalid log level, the valid log levels include D/I/W/E/F" 982498b56bSopenharmony_ci " or DEBUG/INFO/WARN/ERROR/FATAL"}, 992498b56bSopenharmony_ci {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init/kmsg/only_prerelease"}, 1002498b56bSopenharmony_ci {ERR_INVALID_RQST_CMD, "Invalid request cmd, please check sourcecode"}, 1012498b56bSopenharmony_ci {ERR_QUERY_TYPE_INVALID, "Can't query kmsg type logs combined with other types logs."}, 1022498b56bSopenharmony_ci {ERR_INVALID_DOMAIN_STR, "Invalid domain string"}, 1032498b56bSopenharmony_ci {ERR_LOG_PERSIST_FILE_SIZE_INVALID, "Invalid log persist file size, file size should be in range [" 1042498b56bSopenharmony_ci + Size2Str(MIN_LOG_FILE_SIZE) + ", " + Size2Str(MAX_LOG_FILE_SIZE) + "]"}, 1052498b56bSopenharmony_ci {ERR_LOG_PERSIST_FILE_NAME_INVALID, "Invalid log persist file name, file name should not contain [\\/:*?\"<>|]"}, 1062498b56bSopenharmony_ci {ERR_LOG_PERSIST_COMPRESS_BUFFER_EXP, "Invalid Log persist compression buffer"}, 1072498b56bSopenharmony_ci {ERR_LOG_PERSIST_FILE_PATH_INVALID, "Invalid persister file path or persister directory does not exist"}, 1082498b56bSopenharmony_ci {ERR_LOG_PERSIST_COMPRESS_INIT_FAIL, "Log persist compression initialization failed"}, 1092498b56bSopenharmony_ci {ERR_LOG_PERSIST_FILE_OPEN_FAIL, "Log persist open file failed"}, 1102498b56bSopenharmony_ci {ERR_LOG_PERSIST_JOBID_FAIL, "Log persist jobid not exist"}, 1112498b56bSopenharmony_ci {ERR_LOG_PERSIST_TASK_EXISTED, "Log persist task is existed"}, 1122498b56bSopenharmony_ci {ERR_DOMAIN_INVALID, ("Invalid domain, domain should be in range (" + Uint2HexStr(DOMAIN_MIN) 1132498b56bSopenharmony_ci + ", " +Uint2HexStr(DOMAIN_MAX) +"]")}, 1142498b56bSopenharmony_ci {ERR_MSG_LEN_INVALID, "Invalid message length"}, 1152498b56bSopenharmony_ci {ERR_LOG_PERSIST_JOBID_INVALID, "Invalid jobid, jobid should be in range [" + to_string(JOB_ID_MIN) 1162498b56bSopenharmony_ci + ", " + to_string(JOB_ID_MAX) + ")"}, 1172498b56bSopenharmony_ci {ERR_BUFF_SIZE_INVALID, ("Invalid buffer size, buffer size should be in range [" + Size2Str(MIN_BUFFER_SIZE) 1182498b56bSopenharmony_ci + ", " + Size2Str(MAX_BUFFER_SIZE) + "]")}, 1192498b56bSopenharmony_ci {ERR_COMMAND_INVALID, "Mutlti commands can't be used in combination"}, 1202498b56bSopenharmony_ci {ERR_LOG_FILE_NUM_INVALID, "Invalid number of files"}, 1212498b56bSopenharmony_ci {ERR_NOT_NUMBER_STR, "Not a numeric string"}, 1222498b56bSopenharmony_ci {ERR_TOO_MANY_ARGUMENTS, "Too many arguments"}, 1232498b56bSopenharmony_ci {ERR_DUPLICATE_OPTION, "Too many duplicate options"}, 1242498b56bSopenharmony_ci {ERR_INVALID_ARGUMENT, "Invalid argument"}, 1252498b56bSopenharmony_ci {ERR_TOO_MANY_DOMAINS, "Max domain count is " + to_string(MAX_DOMAINS)}, 1262498b56bSopenharmony_ci {ERR_INVALID_SIZE_STR, "Invalid size string"}, 1272498b56bSopenharmony_ci {ERR_TOO_MANY_PIDS, "Max pid count is " + to_string(MAX_PIDS)}, 1282498b56bSopenharmony_ci {ERR_TOO_MANY_TAGS, "Max tag count is " + to_string(MAX_TAGS)}, 1292498b56bSopenharmony_ci {ERR_TAG_STR_TOO_LONG, ("Tag string too long, max length is " + to_string(MAX_TAG_LEN - 1))}, 1302498b56bSopenharmony_ci {ERR_REGEX_STR_TOO_LONG, ("Regular expression too long, max length is " + to_string(MAX_REGEX_STR_LEN - 1))}, 1312498b56bSopenharmony_ci {ERR_FILE_NAME_TOO_LONG, ("File name too long, max length is " + to_string(MAX_FILE_NAME_LEN))}, 1322498b56bSopenharmony_ci {ERR_SOCKET_CLIENT_INIT_FAIL, "Socket client init failed"}, 1332498b56bSopenharmony_ci {ERR_SOCKET_WRITE_MSG_HEADER_FAIL, "Socket rite message header failed"}, 1342498b56bSopenharmony_ci {ERR_SOCKET_WRITE_CMD_FAIL, "Socket write command failed"}, 1352498b56bSopenharmony_ci {ERR_SOCKET_RECEIVE_RSP, "Unable to receive message from socket"}, 1362498b56bSopenharmony_ci {ERR_PERSIST_TASK_EMPTY, "No running persist task, please check"}, 1372498b56bSopenharmony_ci {ERR_JOBID_NOT_EXSIST, "Persist task of this job id doesn't exist, please check"}, 1382498b56bSopenharmony_ci {ERR_TOO_MANY_JOBS, ("Too many jobs are running, max job count is:" + to_string(MAX_JOBS))}, 1392498b56bSopenharmony_ci {ERR_STATS_NOT_ENABLE, "Statistic feature is not enable, " 1402498b56bSopenharmony_ci "please set param persist.sys.hilog.stats true to enable it, " 1412498b56bSopenharmony_ci "further more, you can set persist.sys.hilog.stats.tag true to enable counting log by tags"}, 1422498b56bSopenharmony_ci {ERR_NO_RUNNING_TASK, "No running persistent task"}, 1432498b56bSopenharmony_ci {ERR_NO_PID_PERMISSION, "Permission denied, only shell and root can filter logs by pid"}, 1442498b56bSopenharmony_ci}, RET_FAIL, "Unknown error code"); 1452498b56bSopenharmony_ci 1462498b56bSopenharmony_cistring ErrorCode2Str(int16_t errorCode) 1472498b56bSopenharmony_ci{ 1482498b56bSopenharmony_ci return g_ErrorMsgs.GetValue((uint16_t)errorCode) + " [CODE: " + to_string(errorCode) + "]"; 1492498b56bSopenharmony_ci} 1502498b56bSopenharmony_ci 1512498b56bSopenharmony_ci// Log Types&Strings Map 1522498b56bSopenharmony_cistatic const StringMap g_LogTypes({ 1532498b56bSopenharmony_ci {LOG_INIT, "init"}, {LOG_CORE, "core"}, {LOG_APP, "app"}, {LOG_KMSG, "kmsg"}, 1542498b56bSopenharmony_ci {LOG_ONLY_PRERELEASE, "only_prerelease"} 1552498b56bSopenharmony_ci}, LOG_TYPE_MAX, "invalid"); 1562498b56bSopenharmony_ci 1572498b56bSopenharmony_cistring LogType2Str(uint16_t logType) 1582498b56bSopenharmony_ci{ 1592498b56bSopenharmony_ci return g_LogTypes.GetValue(logType); 1602498b56bSopenharmony_ci} 1612498b56bSopenharmony_ci 1622498b56bSopenharmony_ciuint16_t Str2LogType(const string& str) 1632498b56bSopenharmony_ci{ 1642498b56bSopenharmony_ci return g_LogTypes.GetKey(str); 1652498b56bSopenharmony_ci} 1662498b56bSopenharmony_ci 1672498b56bSopenharmony_cistring ComboLogType2Str(uint16_t shiftType) 1682498b56bSopenharmony_ci{ 1692498b56bSopenharmony_ci vector<uint16_t> types = g_LogTypes.GetAllKeys(); 1702498b56bSopenharmony_ci string str = ""; 1712498b56bSopenharmony_ci uint16_t typeAll = 0; 1722498b56bSopenharmony_ci 1732498b56bSopenharmony_ci for (uint16_t t : types) { 1742498b56bSopenharmony_ci typeAll |= (1 << t); 1752498b56bSopenharmony_ci } 1762498b56bSopenharmony_ci shiftType &= typeAll; 1772498b56bSopenharmony_ci for (uint16_t t: types) { 1782498b56bSopenharmony_ci if ((1 << t) & shiftType) { 1792498b56bSopenharmony_ci shiftType &= (~(1 << t)); 1802498b56bSopenharmony_ci str += (LogType2Str(t) + (shiftType != 0 ? "," : "")); 1812498b56bSopenharmony_ci } 1822498b56bSopenharmony_ci if (shiftType == 0) { 1832498b56bSopenharmony_ci break; 1842498b56bSopenharmony_ci } 1852498b56bSopenharmony_ci } 1862498b56bSopenharmony_ci return str; 1872498b56bSopenharmony_ci} 1882498b56bSopenharmony_ci 1892498b56bSopenharmony_ciuint16_t Str2ComboLogType(const string& str) 1902498b56bSopenharmony_ci{ 1912498b56bSopenharmony_ci uint16_t logTypes = 0; 1922498b56bSopenharmony_ci if (str == "") { 1932498b56bSopenharmony_ci logTypes = (1 << LOG_CORE) | (1 << LOG_APP) | (1 << LOG_ONLY_PRERELEASE); 1942498b56bSopenharmony_ci return logTypes; 1952498b56bSopenharmony_ci } 1962498b56bSopenharmony_ci vector<string> vec; 1972498b56bSopenharmony_ci Split(str, vec); 1982498b56bSopenharmony_ci for (auto& it : vec) { 1992498b56bSopenharmony_ci if (it == "") { 2002498b56bSopenharmony_ci continue; 2012498b56bSopenharmony_ci } 2022498b56bSopenharmony_ci uint16_t t = Str2LogType(it); 2032498b56bSopenharmony_ci if (t == LOG_TYPE_MAX) { 2042498b56bSopenharmony_ci return 0; 2052498b56bSopenharmony_ci } 2062498b56bSopenharmony_ci logTypes |= (1 << t); 2072498b56bSopenharmony_ci } 2082498b56bSopenharmony_ci return logTypes; 2092498b56bSopenharmony_ci} 2102498b56bSopenharmony_ci 2112498b56bSopenharmony_civector<uint16_t> GetAllLogTypes() 2122498b56bSopenharmony_ci{ 2132498b56bSopenharmony_ci return g_LogTypes.GetAllKeys(); 2142498b56bSopenharmony_ci} 2152498b56bSopenharmony_ci 2162498b56bSopenharmony_ci// Log Levels&Strings Map 2172498b56bSopenharmony_cistatic const StringMap g_LogLevels({ 2182498b56bSopenharmony_ci {LOG_DEBUG, "DEBUG"}, {LOG_INFO, "INFO"}, {LOG_WARN, "WARN"}, 2192498b56bSopenharmony_ci {LOG_ERROR, "ERROR"}, {LOG_FATAL, "FATAL"}, {LOG_LEVEL_MAX, "X"} 2202498b56bSopenharmony_ci}, LOG_LEVEL_MIN, "INVALID", [](const string& l1, const string& l2) { 2212498b56bSopenharmony_ci if (l1.length() == l2.length()) { 2222498b56bSopenharmony_ci return std::equal(l1.begin(), l1.end(), l2.begin(), [](char a, char b) { 2232498b56bSopenharmony_ci return std::tolower(a) == std::tolower(b); 2242498b56bSopenharmony_ci }); 2252498b56bSopenharmony_ci } else { 2262498b56bSopenharmony_ci return false; 2272498b56bSopenharmony_ci } 2282498b56bSopenharmony_ci}); 2292498b56bSopenharmony_ci 2302498b56bSopenharmony_cistring LogLevel2Str(uint16_t logLevel) 2312498b56bSopenharmony_ci{ 2322498b56bSopenharmony_ci return g_LogLevels.GetValue(logLevel); 2332498b56bSopenharmony_ci} 2342498b56bSopenharmony_ci 2352498b56bSopenharmony_ciuint16_t Str2LogLevel(const string& str) 2362498b56bSopenharmony_ci{ 2372498b56bSopenharmony_ci return g_LogLevels.GetKey(str); 2382498b56bSopenharmony_ci} 2392498b56bSopenharmony_ci 2402498b56bSopenharmony_ci// Log Levels&Short Strings Map 2412498b56bSopenharmony_cistatic const StringMap g_ShortLogLevels({ 2422498b56bSopenharmony_ci {LOG_DEBUG, "D"}, {LOG_INFO, "I"}, {LOG_WARN, "W"}, 2432498b56bSopenharmony_ci {LOG_ERROR, "E"}, {LOG_FATAL, "F"}, {LOG_LEVEL_MAX, "X"} 2442498b56bSopenharmony_ci}, LOG_LEVEL_MIN, "V", [](const string& l1, const string& l2) { 2452498b56bSopenharmony_ci return (l1.length() == 1 && std::tolower(l1[0]) == std::tolower(l2[0])); 2462498b56bSopenharmony_ci}); 2472498b56bSopenharmony_ci 2482498b56bSopenharmony_cistring LogLevel2ShortStr(uint16_t logLevel) 2492498b56bSopenharmony_ci{ 2502498b56bSopenharmony_ci return g_ShortLogLevels.GetValue(logLevel); 2512498b56bSopenharmony_ci} 2522498b56bSopenharmony_ci 2532498b56bSopenharmony_ciuint16_t ShortStr2LogLevel(const string& str) 2542498b56bSopenharmony_ci{ 2552498b56bSopenharmony_ci return g_ShortLogLevels.GetKey(str); 2562498b56bSopenharmony_ci} 2572498b56bSopenharmony_ci 2582498b56bSopenharmony_ciuint16_t PrettyStr2LogLevel(const string& str) 2592498b56bSopenharmony_ci{ 2602498b56bSopenharmony_ci uint16_t level = ShortStr2LogLevel(str); 2612498b56bSopenharmony_ci if (level == static_cast<uint16_t>(LOG_LEVEL_MIN)) { 2622498b56bSopenharmony_ci return Str2LogLevel(str); 2632498b56bSopenharmony_ci } 2642498b56bSopenharmony_ci return level; 2652498b56bSopenharmony_ci} 2662498b56bSopenharmony_ci 2672498b56bSopenharmony_cistring ComboLogLevel2Str(uint16_t shiftLevel) 2682498b56bSopenharmony_ci{ 2692498b56bSopenharmony_ci vector<uint16_t> levels = g_ShortLogLevels.GetAllKeys(); 2702498b56bSopenharmony_ci string str = ""; 2712498b56bSopenharmony_ci uint16_t levelAll = 0; 2722498b56bSopenharmony_ci 2732498b56bSopenharmony_ci for (uint16_t l : levels) { 2742498b56bSopenharmony_ci levelAll |= (1 << l); 2752498b56bSopenharmony_ci } 2762498b56bSopenharmony_ci shiftLevel &= levelAll; 2772498b56bSopenharmony_ci for (uint16_t l: levels) { 2782498b56bSopenharmony_ci if ((1 << l) & shiftLevel) { 2792498b56bSopenharmony_ci shiftLevel &= (~(1 << l)); 2802498b56bSopenharmony_ci str += (LogLevel2Str(l) + (shiftLevel != 0 ? "," : "")); 2812498b56bSopenharmony_ci } 2822498b56bSopenharmony_ci if (shiftLevel == 0) { 2832498b56bSopenharmony_ci break; 2842498b56bSopenharmony_ci } 2852498b56bSopenharmony_ci } 2862498b56bSopenharmony_ci return str; 2872498b56bSopenharmony_ci} 2882498b56bSopenharmony_ci 2892498b56bSopenharmony_ciuint16_t Str2ComboLogLevel(const string& str) 2902498b56bSopenharmony_ci{ 2912498b56bSopenharmony_ci uint16_t logLevels = 0; 2922498b56bSopenharmony_ci if (str == "") { 2932498b56bSopenharmony_ci logLevels = 0xFFFF; 2942498b56bSopenharmony_ci return logLevels; 2952498b56bSopenharmony_ci } 2962498b56bSopenharmony_ci vector<string> vec; 2972498b56bSopenharmony_ci Split(str, vec); 2982498b56bSopenharmony_ci for (auto& it : vec) { 2992498b56bSopenharmony_ci if (it == "") { 3002498b56bSopenharmony_ci continue; 3012498b56bSopenharmony_ci } 3022498b56bSopenharmony_ci uint16_t t = PrettyStr2LogLevel(it); 3032498b56bSopenharmony_ci if (t == LOG_LEVEL_MIN || t >= LOG_LEVEL_MAX) { 3042498b56bSopenharmony_ci return 0; 3052498b56bSopenharmony_ci } 3062498b56bSopenharmony_ci logLevels |= (1 << t); 3072498b56bSopenharmony_ci } 3082498b56bSopenharmony_ci return logLevels; 3092498b56bSopenharmony_ci} 3102498b56bSopenharmony_ci 3112498b56bSopenharmony_civoid Split(const std::string& src, std::vector<std::string>& dest, const std::string& separator) 3122498b56bSopenharmony_ci{ 3132498b56bSopenharmony_ci std::string str = src; 3142498b56bSopenharmony_ci std::string substring; 3152498b56bSopenharmony_ci std::string::size_type start = 0; 3162498b56bSopenharmony_ci std::string::size_type index; 3172498b56bSopenharmony_ci dest.clear(); 3182498b56bSopenharmony_ci index = str.find_first_of(separator, start); 3192498b56bSopenharmony_ci if (index == std::string::npos) { 3202498b56bSopenharmony_ci dest.emplace_back(str); 3212498b56bSopenharmony_ci return; 3222498b56bSopenharmony_ci } 3232498b56bSopenharmony_ci do { 3242498b56bSopenharmony_ci substring = str.substr(start, index - start); 3252498b56bSopenharmony_ci dest.emplace_back(substring); 3262498b56bSopenharmony_ci start = index + separator.size(); 3272498b56bSopenharmony_ci index = str.find(separator, start); 3282498b56bSopenharmony_ci } while (index != std::string::npos); 3292498b56bSopenharmony_ci substring = str.substr(start); 3302498b56bSopenharmony_ci if (substring != "") { 3312498b56bSopenharmony_ci dest.emplace_back(substring); 3322498b56bSopenharmony_ci } 3332498b56bSopenharmony_ci} 3342498b56bSopenharmony_ci 3352498b56bSopenharmony_ciuint32_t GetBitsCount(uint64_t n) 3362498b56bSopenharmony_ci{ 3372498b56bSopenharmony_ci uint32_t count = 0; 3382498b56bSopenharmony_ci while (n != 0) { 3392498b56bSopenharmony_ci ++count; 3402498b56bSopenharmony_ci n = n & (n-1); 3412498b56bSopenharmony_ci } 3422498b56bSopenharmony_ci return count; 3432498b56bSopenharmony_ci} 3442498b56bSopenharmony_ci 3452498b56bSopenharmony_ciuint16_t GetBitPos(uint64_t n) 3462498b56bSopenharmony_ci{ 3472498b56bSopenharmony_ci if (!(n && (!(n & (n-1))))) { // only accpet the number which is power of 2 3482498b56bSopenharmony_ci return 0; 3492498b56bSopenharmony_ci } 3502498b56bSopenharmony_ci 3512498b56bSopenharmony_ci uint16_t i = 0; 3522498b56bSopenharmony_ci while (n >> (i++)) {} 3532498b56bSopenharmony_ci i--; 3542498b56bSopenharmony_ci return i-1; 3552498b56bSopenharmony_ci} 3562498b56bSopenharmony_ci 3572498b56bSopenharmony_cienum class Radix { 3582498b56bSopenharmony_ci RADIX_DEC, 3592498b56bSopenharmony_ci RADIX_HEX, 3602498b56bSopenharmony_ci}; 3612498b56bSopenharmony_citemplate<typename T> 3622498b56bSopenharmony_cistatic string Num2Str(T num, Radix radix) 3632498b56bSopenharmony_ci{ 3642498b56bSopenharmony_ci stringstream ss; 3652498b56bSopenharmony_ci auto r = std::dec; 3662498b56bSopenharmony_ci if (radix == Radix::RADIX_HEX) { 3672498b56bSopenharmony_ci r = std::hex; 3682498b56bSopenharmony_ci } 3692498b56bSopenharmony_ci ss << r << num; 3702498b56bSopenharmony_ci return ss.str(); 3712498b56bSopenharmony_ci} 3722498b56bSopenharmony_ci 3732498b56bSopenharmony_citemplate<typename T> 3742498b56bSopenharmony_cistatic void Str2Num(const string& str, T& num, Radix radix) 3752498b56bSopenharmony_ci{ 3762498b56bSopenharmony_ci T i = 0; 3772498b56bSopenharmony_ci std::stringstream ss; 3782498b56bSopenharmony_ci auto r = std::dec; 3792498b56bSopenharmony_ci if (radix == Radix::RADIX_HEX) { 3802498b56bSopenharmony_ci r = std::hex; 3812498b56bSopenharmony_ci } 3822498b56bSopenharmony_ci ss << r << str; 3832498b56bSopenharmony_ci ss >> i; 3842498b56bSopenharmony_ci num = i; 3852498b56bSopenharmony_ci return; 3862498b56bSopenharmony_ci} 3872498b56bSopenharmony_ci 3882498b56bSopenharmony_cistring Uint2DecStr(uint32_t i) 3892498b56bSopenharmony_ci{ 3902498b56bSopenharmony_ci return Num2Str(i, Radix::RADIX_DEC); 3912498b56bSopenharmony_ci} 3922498b56bSopenharmony_ci 3932498b56bSopenharmony_ciuint32_t DecStr2Uint(const string& str) 3942498b56bSopenharmony_ci{ 3952498b56bSopenharmony_ci uint32_t i = 0; 3962498b56bSopenharmony_ci Str2Num(str, i, Radix::RADIX_DEC); 3972498b56bSopenharmony_ci return i; 3982498b56bSopenharmony_ci} 3992498b56bSopenharmony_ci 4002498b56bSopenharmony_cistring Uint2HexStr(uint32_t i) 4012498b56bSopenharmony_ci{ 4022498b56bSopenharmony_ci return Num2Str(i, Radix::RADIX_HEX); 4032498b56bSopenharmony_ci} 4042498b56bSopenharmony_ci 4052498b56bSopenharmony_ciuint32_t HexStr2Uint(const string& str) 4062498b56bSopenharmony_ci{ 4072498b56bSopenharmony_ci uint32_t i = 0; 4082498b56bSopenharmony_ci Str2Num(str, i, Radix::RADIX_HEX); 4092498b56bSopenharmony_ci return i; 4102498b56bSopenharmony_ci} 4112498b56bSopenharmony_ci 4122498b56bSopenharmony_ci#if !defined(__WINDOWS__) and !defined(__LINUX__) 4132498b56bSopenharmony_cistring GetProgName() 4142498b56bSopenharmony_ci{ 4152498b56bSopenharmony_ci#ifdef HILOG_USE_MUSL 4162498b56bSopenharmony_ci return program_invocation_short_name; 4172498b56bSopenharmony_ci#else 4182498b56bSopenharmony_ci return getprogname(); 4192498b56bSopenharmony_ci#endif 4202498b56bSopenharmony_ci} 4212498b56bSopenharmony_ci#endif 4222498b56bSopenharmony_ci 4232498b56bSopenharmony_cistring GetNameByPid(uint32_t pid) 4242498b56bSopenharmony_ci{ 4252498b56bSopenharmony_ci char path[CMDLINE_PATH_LEN] = { 0 }; 4262498b56bSopenharmony_ci if (snprintf_s(path, CMDLINE_PATH_LEN, CMDLINE_PATH_LEN - 1, "/proc/%d/cmdline", pid) <= 0) { 4272498b56bSopenharmony_ci return ""; 4282498b56bSopenharmony_ci } 4292498b56bSopenharmony_ci char cmdline[CMDLINE_LEN] = { 0 }; 4302498b56bSopenharmony_ci int i = 0; 4312498b56bSopenharmony_ci FILE *fp = fopen(path, "r"); 4322498b56bSopenharmony_ci if (fp == nullptr) { 4332498b56bSopenharmony_ci return ""; 4342498b56bSopenharmony_ci } 4352498b56bSopenharmony_ci while (i < (CMDLINE_LEN - 1)) { 4362498b56bSopenharmony_ci char c = static_cast<char>(fgetc(fp)); 4372498b56bSopenharmony_ci // 0. don't need args of cmdline 4382498b56bSopenharmony_ci // 1. ignore unvisible character 4392498b56bSopenharmony_ci if (!isgraph(c)) { 4402498b56bSopenharmony_ci break; 4412498b56bSopenharmony_ci } 4422498b56bSopenharmony_ci cmdline[i] = c; 4432498b56bSopenharmony_ci i++; 4442498b56bSopenharmony_ci } 4452498b56bSopenharmony_ci (void)fclose(fp); 4462498b56bSopenharmony_ci return cmdline; 4472498b56bSopenharmony_ci} 4482498b56bSopenharmony_ci 4492498b56bSopenharmony_ciuint32_t GetPPidByPid(uint32_t pid) 4502498b56bSopenharmony_ci{ 4512498b56bSopenharmony_ci uint32_t ppid = 0; 4522498b56bSopenharmony_ci char path[STATUS_PATH_LEN] = { 0 }; 4532498b56bSopenharmony_ci if (snprintf_s(path, STATUS_PATH_LEN, STATUS_PATH_LEN - 1, "/proc/%u/status", pid) <= 0) { 4542498b56bSopenharmony_ci return ppid; 4552498b56bSopenharmony_ci } 4562498b56bSopenharmony_ci FILE *fp = fopen(path, "r"); 4572498b56bSopenharmony_ci if (fp == nullptr) { 4582498b56bSopenharmony_ci return ppid; 4592498b56bSopenharmony_ci } 4602498b56bSopenharmony_ci char buf[STATUS_LEN] = { 0 }; 4612498b56bSopenharmony_ci size_t ret = fread(buf, sizeof(char), STATUS_LEN - 1, fp); 4622498b56bSopenharmony_ci (void)fclose(fp); 4632498b56bSopenharmony_ci if (ret <= 0) { 4642498b56bSopenharmony_ci return ppid; 4652498b56bSopenharmony_ci } else { 4662498b56bSopenharmony_ci buf[ret++] = '\0'; 4672498b56bSopenharmony_ci } 4682498b56bSopenharmony_ci char *ppidLoc = strstr(buf, "PPid:"); 4692498b56bSopenharmony_ci if ((ppidLoc == nullptr) || (sscanf_s(ppidLoc, "PPid:%d", &ppid) == -1)) { 4702498b56bSopenharmony_ci return ppid; 4712498b56bSopenharmony_ci } 4722498b56bSopenharmony_ci std::string ppidName = GetNameByPid(ppid); 4732498b56bSopenharmony_ci // ppid fork the sh to execute hilog, sh is not wanted ppid 4742498b56bSopenharmony_ci if (std::find(std::begin(SH_NAMES), std::end(SH_NAMES), ppidName) != std::end(SH_NAMES)) { 4752498b56bSopenharmony_ci return GetPPidByPid(ppid); 4762498b56bSopenharmony_ci } 4772498b56bSopenharmony_ci return ppid; 4782498b56bSopenharmony_ci} 4792498b56bSopenharmony_ci 4802498b56bSopenharmony_ciuint64_t GenerateHash(const char *p, size_t size) 4812498b56bSopenharmony_ci{ 4822498b56bSopenharmony_ci static const uint64_t PRIME = 0x100000001B3ULL; 4832498b56bSopenharmony_ci static const uint64_t BASIS = 0xCBF29CE484222325ULL; 4842498b56bSopenharmony_ci uint64_t ret {BASIS}; 4852498b56bSopenharmony_ci unsigned long i = 0; 4862498b56bSopenharmony_ci while (i < size) { 4872498b56bSopenharmony_ci ret ^= *(p + i); 4882498b56bSopenharmony_ci ret *= PRIME; 4892498b56bSopenharmony_ci i++; 4902498b56bSopenharmony_ci } 4912498b56bSopenharmony_ci return ret; 4922498b56bSopenharmony_ci} 4932498b56bSopenharmony_ci 4942498b56bSopenharmony_civoid PrintErrorno(int err) 4952498b56bSopenharmony_ci{ 4962498b56bSopenharmony_ci constexpr int bufSize = 256; 4972498b56bSopenharmony_ci char buf[bufSize] = { 0 }; 4982498b56bSopenharmony_ci#ifndef __WINDOWS__ 4992498b56bSopenharmony_ci (void)strerror_r(err, buf, bufSize); 5002498b56bSopenharmony_ci#else 5012498b56bSopenharmony_ci (void)strerror_s(buf, bufSize, err); 5022498b56bSopenharmony_ci#endif 5032498b56bSopenharmony_ci std::cerr << "Errno: " << err << ", " << buf << std::endl; 5042498b56bSopenharmony_ci} 5052498b56bSopenharmony_ci 5062498b56bSopenharmony_ciint WaitingToDo(int max, const string& path, function<int(const string &path)> func) 5072498b56bSopenharmony_ci{ 5082498b56bSopenharmony_ci chrono::steady_clock::time_point start = chrono::steady_clock::now(); 5092498b56bSopenharmony_ci chrono::milliseconds wait(max); 5102498b56bSopenharmony_ci while (true) { 5112498b56bSopenharmony_ci if (func(path) != RET_FAIL) { 5122498b56bSopenharmony_ci cout << "waiting for " << path << " successfully!" << endl; 5132498b56bSopenharmony_ci return RET_SUCCESS; 5142498b56bSopenharmony_ci } 5152498b56bSopenharmony_ci 5162498b56bSopenharmony_ci std::this_thread::sleep_for(10ms); 5172498b56bSopenharmony_ci if ((chrono::steady_clock::now() - start) > wait) { 5182498b56bSopenharmony_ci cerr << "waiting for " << path << " failed!" << endl; 5192498b56bSopenharmony_ci return RET_FAIL; 5202498b56bSopenharmony_ci } 5212498b56bSopenharmony_ci } 5222498b56bSopenharmony_ci} 5232498b56bSopenharmony_ci 5242498b56bSopenharmony_cistd::wstring StringToWstring(const std::string& input) 5252498b56bSopenharmony_ci{ 5262498b56bSopenharmony_ci std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; 5272498b56bSopenharmony_ci return converter.from_bytes(input); 5282498b56bSopenharmony_ci} 5292498b56bSopenharmony_ci} // namespace HiviewDFX 5302498b56bSopenharmony_ci} // namespace OHOS 531