1 /*
2 * Copyright (c) 2021 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 "common_utils.h"
17
18 #include <cstdint>
19 #include <cstdio>
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <sstream>
23 #include <string>
24 #include <sys/wait.h>
25 #include <sys/syscall.h>
26 #include <unistd.h>
27 #include <vector>
28
29 #include "securec.h"
30 #include "time_util.h"
31
32 using namespace std;
33 namespace OHOS {
34 namespace HiviewDFX {
35 namespace CommonUtils {
ExecCommand(const std::string & cmd,const std::vector<std::string> & args)36 int ExecCommand(const std::string &cmd, const std::vector<std::string> &args)
37 {
38 pid_t pid = fork();
39 if (pid < 0) {
40 return -1;
41 } else if (pid == 0) {
42 // Redirect the stdout to /dev/null
43 int fd = open("/dev/null", O_WRONLY);
44 // follow standard, although dup2 may handle the case of invalid oldfd
45 if (fd >= 0) {
46 dup2(fd, STDOUT_FILENO);
47 close(fd);
48 }
49
50 std::vector<char *> argv;
51 argv.push_back(const_cast<char *>(cmd.c_str()));
52 for (const auto &arg : args) {
53 argv.push_back(const_cast<char *>(arg.c_str()));
54 }
55 argv.push_back(0);
56 execv(argv[0], &argv[0]);
57 }
58 constexpr uint64_t maxWaitingTime = 60; // 60 seconds
59 uint64_t remainedTime = maxWaitingTime * NS_PER_SECOND;
60 while (remainedTime > 0) {
61 uint64_t startTime = TimeUtil::GetNanoTime();
62 int status = 0;
63 waitpid(pid, &status, WNOHANG);
64 if (WIFEXITED(status)) {
65 return 0;
66 }
67 sleep(1);
68 uint64_t duration = TimeUtil::GetNanoTime() - startTime;
69 remainedTime = (remainedTime > duration) ? (remainedTime - duration) : 0;
70 }
71
72 return -1;
73 }
74
GetProcNameByPid(pid_t pid)75 std::string GetProcNameByPid(pid_t pid)
76 {
77 std::string result;
78 char buf[BUF_SIZE_256] = {0};
79 (void)snprintf_s(buf, BUF_SIZE_256, BUF_SIZE_256 - 1, "/proc/%d/cmdline", pid);
80 FileUtil::LoadStringFromFile(std::string(buf, strlen(buf)), result);
81 auto pos = result.find_last_not_of(" \n\r\t");
82 if (pos == std::string::npos) {
83 return result;
84 }
85 result.erase(pos + 1);
86 return result.c_str();
87 }
88
GetPidByName(const std::string & processName)89 pid_t GetPidByName(const std::string& processName)
90 {
91 pid_t pid = -1;
92 std::string cmd = "pidof " + processName;
93
94 char buffer[BUF_SIZE_256] = {'\0'};
95 FILE* fp = popen(cmd.c_str(), "r");
96 if (fp != nullptr) {
97 while (fgets(buffer, sizeof(buffer) - 1, fp) != nullptr) {}
98 std::istringstream istr(buffer);
99 istr >> pid;
100 pclose(fp);
101 }
102 return pid;
103 }
104
IsTheProcessExist(pid_t pid)105 bool IsTheProcessExist(pid_t pid)
106 {
107 int ret = syscall(SYS_tgkill, pid, pid, 0);
108 if (ret != 0 && errno == ESRCH) {
109 return false;
110 }
111 return true;
112 }
113
IsSpecificCmdExist(const std::string & fullPath)114 bool IsSpecificCmdExist(const std::string& fullPath)
115 {
116 return access(fullPath.c_str(), X_OK) == 0;
117 }
118
WriteCommandResultToFile(int fd,const std::string & cmd)119 bool WriteCommandResultToFile(int fd, const std::string& cmd)
120 {
121 if (cmd.empty()) {
122 return false;
123 }
124 char buffer[BUF_SIZE_256];
125 FILE* fp = popen(cmd.c_str(), "r");
126 if (fp != nullptr) {
127 while (fgets(buffer, sizeof(buffer), fp) != nullptr) {
128 FileUtil::SaveStringToFd(fd, buffer);
129 }
130 pclose(fp);
131 return true;
132 }
133 return false;
134 }
135 }
136 } // namespace HiviewDFX
137 } // namespace OHOS
138