1 /*
2 * Copyright (c) 2022-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 #ifndef DFX_MUSL_CUTIL_H
16 #define DFX_MUSL_CUTIL_H
17
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 #include <syscall.h>
22 #include <time.h>
23 #include <unistd.h>
24 #include "dfx_define.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 #ifdef ENABLE_MUSL_CUTIL
31 static const char PID_STR_NAME[] = "Pid:";
32
ReadStringFromFile(const char * path,char * dst,size_t dstSz)33 static bool ReadStringFromFile(const char* path, char* dst, size_t dstSz)
34 {
35 char name[NAME_LEN];
36 char nameFilter[NAME_LEN];
37 memset(name, 0, sizeof(name));
38 memset(nameFilter, 0, sizeof(nameFilter));
39
40 int fd = -1;
41 fd = OHOS_TEMP_FAILURE_RETRY(open(path, O_RDONLY));
42 if (fd < 0) {
43 return false;
44 }
45
46 int nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, name, NAME_LEN -1));
47 if (nRead == -1) {
48 close(fd);
49 return false;
50 }
51
52 char* p = name;
53 int i = 0;
54 while (*p != '\0') {
55 if ((*p == '\n') || (i == NAME_LEN)) {
56 break;
57 }
58 nameFilter[i] = *p;
59 p++, i++;
60 }
61 nameFilter[NAME_LEN - 1] = '\0';
62
63 size_t cpyLen = strlen(nameFilter) + 1;
64 if (cpyLen > dstSz) {
65 cpyLen = dstSz;
66 }
67 memcpy(dst, nameFilter, cpyLen);
68 close(fd);
69 return true;
70 }
71
GetThreadName(char * buffer,size_t bufferSz)72 bool GetThreadName(char* buffer, size_t bufferSz)
73 {
74 return ReadStringFromFile(PROC_SELF_COMM_PATH, buffer, bufferSz);
75 }
76
GetThreadNameByTid(int32_t tid,char * buffer,size_t bufferSz)77 bool GetThreadNameByTid(int32_t tid, char* buffer, size_t bufferSz)
78 {
79 char threadNamePath[NAME_LEN] = { 0 };
80 if (snprintf(threadNamePath, sizeof(threadNamePath), "/proc/%d/comm", tid) <= 0) {
81 return false;
82 }
83 return ReadStringFromFile(threadNamePath, buffer, bufferSz);
84 }
85
GetProcessName(char * buffer,size_t bufferSz)86 bool GetProcessName(char* buffer, size_t bufferSz)
87 {
88 return ReadStringFromFile(PROC_SELF_CMDLINE_PATH, buffer, bufferSz);
89 }
90
GetRealPid(void)91 pid_t GetRealPid(void)
92 {
93 pid_t pid = syscall(SYS_getpid);
94 int fd = OHOS_TEMP_FAILURE_RETRY(open(PROC_SELF_STATUS_PATH, O_RDONLY));
95 if (fd < 0) {
96 return pid;
97 }
98
99 char buf[LOG_BUF_LEN];
100 int i = 0;
101 char b;
102 ssize_t nRead = 0;
103 while (1) {
104 nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, &b, sizeof(char)));
105 if (nRead <= 0 || b == '\0') {
106 break;
107 }
108
109 if (b == '\n' || i == LOG_BUF_LEN) {
110 if (strncmp(buf, PID_STR_NAME, strlen(PID_STR_NAME)) == 0) {
111 (void)sscanf(buf, "%*[^0-9]%d", &pid);
112 break;
113 }
114 i = 0;
115 (void)memset(buf, '\0', sizeof(buf));
116 continue;
117 }
118 buf[i] = b;
119 i++;
120 }
121 close(fd);
122 return pid;
123 }
124
GetTimeMilliseconds(void)125 uint64_t GetTimeMilliseconds(void)
126 {
127 struct timespec ts;
128 (void)clock_gettime(CLOCK_REALTIME, &ts);
129 return ((uint64_t)ts.tv_sec * NUMBER_ONE_THOUSAND) + // 1000 : second to millisecond convert ratio
130 (((uint64_t)ts.tv_nsec) / NUMBER_ONE_MILLION); // 1000000 : nanosecond to millisecond convert ratio
131 }
132
133 #endif
134 #ifdef __cplusplus
135 }
136 #endif
137 #endif