popen()替代方案

我的问题是这个问题的延伸: popen创造了一个额外的过程

动机:

1)我的程序需要创建一个在文件上tail的子项。 我需要逐行处理输出。 这就是为什么我使用popen因为它返回FILE *。 我可以轻松获取单行,执行我需要做的操作并打印它。

popen的一个问题是你没有得到孩子的pid(在我的情况下是tail命令)。

2)我的程序不应该在孩子完成之前退出。 所以我需要wait ; 但没有pid,我不能这样做。

我怎样才能实现这两个目标?

一个可能的(kludge)解决方案:执行execvp(“tail -f file> tmpfile”)并继续读取tmpfile。 不过,我不确定这个解决方案有多好。

你为什么不使用pipe / fork / exec方法?

 pid_t pid = 0; int pipefd[2]; FILE* output; char line[256]; int status; pipe(pipefd); //create a pipe pid = fork(); //span a child process if (pid == 0) { // Child. Let's redirect its standard output to our pipe and replace process with tail close(pipefd[0]); dup2(pipefd[1], STDOUT_FILENO); dup2(pipefd[1], STDERR_FILENO); execl("/usr/bin/tail", "/usr/bin/tail", "-f", "path/to/your/file", (char*) NULL); } //Only parent gets here. Listen to what the tail says close(pipefd[1]); output = fdopen(pipefd[0], "r"); while(fgets(line, sizeof(line), output)) //listen to what tail writes to its standard output { //if you need to kill the tail application, just kill it: if(something_goes_wrong) kill(pid, SIGKILL); } //or wait for the child process to terminate waitpid(pid, &status, 0); 
  1. 您可以使用pipeexec*系列和fdopen 。 这是非标准的,但popen也是如此。
  2. 你不需要wait 。 只需读取管道到EOF
  3. execvp("tail -f file > tmpfile")不起作用,重定向是shell的一个function,你不在这里运行shell。 即使它有效,也将是一个糟糕的解决方案。 假设您已读到文件的末尾,但子进程尚未结束。 你是做什么?

可以使用wait因为它不希望PID等待,只是等待任何子进程退出。 如果您已经创建了其他子进程,则可以跟踪它们,如果wait返回未知的PID,您可以假设它来自您的popen进程。

我不确定为什么你需要孩子的进程ID。 当孩子退出时,您的管道读数将返回EOF。 如果您需要终止孩子,只需关闭管道即可。