0
我試圖使用匿名管道作爲子進程讀取的文件的替代品。我遇到的問題是子流程掛起,我想,因爲它不能識別已經到達「文件」(管道)的末尾。popen用/ dev/fd/n匿名管道掛起子進程
下面是我在做什麼一些示例代碼:
#include <stdio.h>
#include <unistd.h>
#include <sys/fcntl.h>
int main()
{
int pipefd[2];
pipe(pipefd);
fcntl(pipefd[0], F_SETFL, O_NONBLOCK); // necessary?
char cmd[128];
snprintf(cmd, sizeof(cmd), "cat /dev/fd/%i", pipefd[0]);
printf("Command: %s\n", cmd);
#if 1
// This works
write(pipefd[1], "line1\n", 6);
write(pipefd[1], "line2\n", 6);
write(pipefd[1], "line3\n", 6);
close(pipefd[1]);
#endif
FILE* fp;
if ((fp = popen(cmd, "r")) != NULL)
{
// fcntl(fileno(fp), F_SETFL, O_NONBLOCK); // causes SIGPIPE
#if 0
// This doesn't work
write(pipefd[1], "line1\n", 6);
write(pipefd[1], "line2\n", 6);
write(pipefd[1], "line3\n", 6);
close(pipefd[1]);
#endif
char buffer[1024];
while (fgets(buffer, sizeof(buffer), fp) != NULL)
printf("%s", buffer);
printf("retcode: %i\n", pclose(fp));
}
close(pipefd[0]);
return 0;
}
上述作品給出的代碼。在其中創建一個管道,並使用管道的讀取端創建一個命令,在這種情況下,使用cat
。在工作版本中,我將數據寫入管道的寫入端,然後使用popen
啓動子進程,並從子進程讀取stdout直到它結束。
我需要做的是將創建子進程(請參閱#if 0
塊)後寫入管道。最終,它將以單獨的線程結束。但是,在popen
調用之後切換意味着子進程不會結束(掛起),我看不出原因。
我已經嘗試過讓各種流無阻塞,但是在子流程流上這樣做只會導致SIGPIPE失敗。
有誰知道如何得到這個工作?
謝謝!
在popen之前設置pipefd [1]的FD_CLOEXEC標誌。 –
太棒了!謝謝!!你想做出這個答案,我會標記完成! –