gpt4 book ai didi

c++ - 从 popen 获取 PID

转载 作者:可可西里 更新时间:2023-11-01 18:26:21 35 4
gpt4 key购买 nike

我有一个程序使用 popen() 来打开和读取 shell 命令的输出。问题是,据我所知,没有简单的方法来获取正在运行的进程的 PID,因此,如果它被卡住,你不能杀死它。所以问题是,如何从使用 popen 打开的进程中检索 PID?

最佳答案

我想出的解决方案(和普遍共识)是创建一个新的 popen 函数,它允许我检索 PID。由于我无法在 SO 上找到一个简单的示例,因此我想发布我的实现,希望它能帮助其他人。欢迎提供反馈和替代解决方案。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <errno.h>
#include <string>
#include <sstream>

using namespace std;

#define READ 0
#define WRITE 1
FILE * popen2(string command, string type, int & pid)
{
pid_t child_pid;
int fd[2];
pipe(fd);

if((child_pid = fork()) == -1)
{
perror("fork");
exit(1);
}

/* child process */
if (child_pid == 0)
{
if (type == "r")
{
close(fd[READ]); //Close the READ end of the pipe since the child's fd is write-only
dup2(fd[WRITE], 1); //Redirect stdout to pipe
}
else
{
close(fd[WRITE]); //Close the WRITE end of the pipe since the child's fd is read-only
dup2(fd[READ], 0); //Redirect stdin to pipe
}

setpgid(child_pid, child_pid); //Needed so negative PIDs can kill children of /bin/sh
execl("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL);
exit(0);
}
else
{
if (type == "r")
{
close(fd[WRITE]); //Close the WRITE end of the pipe since parent's fd is read-only
}
else
{
close(fd[READ]); //Close the READ end of the pipe since parent's fd is write-only
}
}

pid = child_pid;

if (type == "r")
{
return fdopen(fd[READ], "r");
}

return fdopen(fd[WRITE], "w");
}

int pclose2(FILE * fp, pid_t pid)
{
int stat;

fclose(fp);
while (waitpid(pid, &stat, 0) == -1)
{
if (errno != EINTR)
{
stat = -1;
break;
}
}

return stat;
}

int main()
{
int pid;
string command = "ping 8.8.8.8";
FILE * fp = popen2(command, "r", pid);
char command_out[100] = {0};
stringstream output;

//Using read() so that I have the option of using select() if I want non-blocking flow
while (read(fileno(fp), command_out, sizeof(command_out)-1) != 0)
{
output << string(command_out);
kill(-pid, 9);
memset(&command_out, 0, sizeof(command_out));
}

string token;
while (getline(output, token, '\n'))
printf("OUT: %s\n", token.c_str());

pclose2(fp, pid);

return 0;
}

关于c++ - 从 popen 获取 PID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26852198/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com