1 /*
2 * Copyright (C) 2025 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 #include "adlt_common.h"
16
read_pipe(int pipe_id)17 std::string read_pipe(int pipe_id) {
18 std::string str;
19 char buf[1024];
20 int ret;
21 while ((ret = read(pipe_id, buf, sizeof(buf))) > 0) {
22 str.append(buf, ret);
23 }
24 return str;
25 }
26
wait_process(int pid,int expect_ret)27 int wait_process(int pid, int expect_ret) {
28 int wstatus;
29 pid_t w = waitpid(pid, &wstatus, 0);
30 if (w == -1) {
31 t_error("%s: wait for child process failed\n", __func__);
32 return errno;
33 }
34
35 int err = WEXITSTATUS(wstatus);
36 if (WIFEXITED(wstatus)) {
37 if (err != expect_ret) {
38 printf("%s: exited with status=%d\n", __func__, err);
39 }
40 } else if (WIFSIGNALED(wstatus)) {
41 printf("%s: killed by signal %d\n", __func__, WTERMSIG(wstatus));
42 } else if (WIFSTOPPED(wstatus)) {
43 printf("%s: stopped by signal %d\n", __func__, WSTOPSIG(wstatus));
44 } else {
45 printf("%s: stopped by signal %d\n", __func__, WSTOPSIG(wstatus));
46 }
47
48 return err;
49 }
50
run_subprocess(std::function<void ()> func,int & child_pid)51 int run_subprocess(std::function<void()> func, int &child_pid) {
52 pid_t pid = fork();
53 if (pid < 0) {
54 t_error("%s: failed to fork child process %d\n", __func__, errno);
55 return errno;
56 }
57
58 // child process
59 if (pid == 0) {
60 func();
61 int ret = errno;
62 exit(ret);
63 }
64
65 // parent process
66 child_pid = pid;
67 return wait_process(pid);
68 }
69
run_subprocess(std::function<void ()> func,int & child_pid,const std::string & file)70 int run_subprocess(std::function<void()> func, int &child_pid, const std::string &file) {
71 pid_t pid = fork();
72 if (pid < 0) {
73 t_error("%s: failed to fork child process %d\n", __func__, errno);
74 return errno;
75 }
76
77 // child process
78 if (pid == 0) {
79 int fd = open((file + "." + std::to_string(getpid())).c_str(), O_CREAT | O_TRUNC | O_RDWR, 0644);
80 if (fd < 0) {
81 int ret = errno;
82 exit(ret);
83 }
84
85 dup2(fd, STDOUT_FILENO);
86 dup2(fd, STDERR_FILENO);
87 close(fd);
88
89 func();
90
91 fflush(stdout);
92 fflush(stderr);
93
94 int ret = errno;
95 exit(ret);
96 }
97
98 // parent process
99 child_pid = pid;
100 return wait_process(pid);
101 }
102
run_self_command(const std::string & args,const std::string & env)103 int run_self_command(const std::string &args, const std::string &env) {
104 char *self_command_path = realpath("/proc/self/exe", nullptr);
105 if (!self_command_path) {
106 t_error("%s: failed to get self command path\n", __func__);
107 return -1;
108 }
109
110 std::stringstream ss;
111 ss << env << ' ' << self_command_path << ' ' << args;
112 free(self_command_path);
113
114 return system(ss.str().c_str());
115 }