我正在编写一个应用程序,它将根据用户输入启动某些进程(fork和exec),并且应该告知用户这些进程中的每个错误(打印一些内部ID +由进程写入stderr的消息)。我也想检测现有流程。我遇到问题,执行execl()命令后无法接收数据。在epoll_wait循环中接收测试数据,但exec调用的进程似乎没有向stderr写任何东西,甚至没有结束(我不知道我是否正确,但我希望管道在它之后可读“#39 ;当进程退出时,s写入结束已经关闭)。一些代码重现了我的问题:
#include <unistd.h>
#include <sys/epoll.h>
#include <stdio.h>
#include <thread>
#include <stdlib.h>
#include <sys/wait.h>
thread_local int epoll;
int do_fork()
{
int pip[2];
pipe(pip);
int pid = fork();
if (pid == 0)
{
dup2(pip[1], STDERR_FILENO);
close(pip[0]);
close(pip[1]);
write(STDERR_FILENO, "test data", 10);
sleep(3);
//exit(1);
execl("tr", "tr", NULL); //this process will end immediately and write error on stderr
}
else
{
printf("PID %d\n", pid);
close(pip[1]);
epoll_event ev;
ev.data.fd = pip[0];
ev.events = EPOLLIN | EPOLLRDHUP | EPOLLHUP;
printf("pipe %d\n", pip[0]);
epoll_ctl(epoll, EPOLL_CTL_ADD, pip[0], &ev);
}
}
int thread()
{
epoll_event events[10];
epoll = epoll_create1(0);
epoll_event ev;
ev.data.fd = STDIN_FILENO;
ev.events = EPOLLIN;
epoll_ctl(epoll, EPOLL_CTL_ADD, STDIN_FILENO, &ev);
char buf[1000];
while(true)
{
int r = epoll_wait(epoll, events, 10, -1);
printf("r = %d\n", r);
for (int i = 0; i < r; ++i)
{
if(events[i].data.fd == STDIN_FILENO)
{
int t = read(events[i].data.fd, buf, 1000);
do_fork();
}
else
{
printf("event? %d\n", events[i].events);
printf("pipe %d\n", events[i].data.fd);
int t = read(events[i].data.fd, buf, 1000);
printf("t == %d\n", t);
if(t == -1)
printf("errno: %d\n", errno);
if(events[i].events & EPOLLHUP || t == 0)
{
epoll_ctl(epoll, EPOLL_CTL_DEL, events[i].data.fd, NULL);
if(close(events[i].data.fd) == -1)
printf("cannot close fd\n");
}
}
}
}
return 0;
}
int main()
{
std::thread t{thread};
t.detach();
while(true);
}