[英]Trouble with pipes, dup, close and exec in C
好。 我有點理解管道如何工作以及為什么在任何子進程中exec之前使用dup / dup2。
但我需要'close(int fd)'的幫助。 為了說清楚,我想問你任何偽代碼或任何C代碼示例,它執行以下操作:
只用一根煙斗就可以做到這一點嗎?
對我來說,棘手的事情不是創建管道並使用dup2和東西重定向通道,它知道何時何地關閉()所有fd通道。
如果你能解釋我如何做這樣的事情,以及何時何地以一個例子來關閉頻道,我想我絕對會理解這一切。
非常感謝你們。
以下是一個完整的例子。 WhozCraig已經告訴父母在繼續之前不需要等待孩子1結束,因為孩子2必須在EOF之前讀取管道。 (相反,父級必須不等待,因為管道緩沖區可能不足以容納所有文件數據。)當然只需要一個管道 ,其中子級1寫入一端而子級2讀取另一端。 因此,不需要dup
。
父母何時何地必須關閉管道渠道?
只要需要管道末端的子項打開它,父級可以在不再需要它們時立即關閉管道末端,即在我們的情況下,父級可以關閉(其描述符)寫入結束之后子級1已經被分叉,並且父級可以在子級2被分叉之后關閉讀取端,因為子級繼承了管道描述符,並且它們保持可用直到子級在退出時關閉它們。
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
main(int argc, char *argv[])
{
if (argc <= 1) return 1;
int fd = open(argv[1], O_RDONLY); // Parent gets a fd from a file.
if (fd < 0) return perror(argv[1]), 1;
int pipefd[2];
if (pipe(pipefd) < 0) return perror("pipe"), 1;
char in[8], out[8];
sprintf(in, "FD:%d", fd); // reads data from the open() func fd
sprintf(out, "FD:%d", pipefd[1]); // writes the output in a pipe
switch (fork())
{ // Parent creates a child which execs to another program, e. g. "socat"
case -1: return perror("fork 1"), 1;
case 0: execlp("socat", "socat", "-u", in, out, NULL);
return perror("execlp 1"), 1;
}
close(pipefd[1]); // parent may close write end, since child has it open
sprintf(in, "FD:%d", pipefd[0]); // read from the pipe created before
sprintf(out, "FD:%d", 1); // write the output in the stdo
switch (fork())
{ // Same parent then creates another child which is going to exec
case -1: return perror("fork 2"), 1;
case 0: execlp("socat", "socat", "-u", in, out, NULL);
return perror("execlp 2"), 1;
}
close(pipefd[0]); // parent may close read end, since child has it open
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.