【发布时间】:2014-02-16 07:36:59
【问题描述】:
给定一个这种格式的命令:
cat < inputfile.txt | tee outputfile.txt
我正在尝试让 inputfile.txt 写入管道,然后从管道中读取 outputfile.txt,为此我编写了以下函数:
void piperead(char** input, int* fd, int start) {
dup2(fd[0], 0);
close(fd[1]);
execl("usr/bin/tee", "usr/bin/tee", input[start + 1], NULL);
}
void pipewrite(char** input, int* fd, int start, int end) {
dup2(fd[1], 1);
close(fd[0]);
execl("usr/bin/cat", "usr/bin/tee", input[start + 2], NULL);
}
void dopiping(char** input, int start, int end) {
int fd[2];
if (pipe(fd) == -1) {
cout << "Error: Pipe failed." << endl;
exit(1);
}
int pid = fork();
switch(pid = fork()) {
case 0:
piperead(input, fd, start, end);
default:
pipewrite(input, fd, end + 1);
case -1:
exit(1);
}
}
我已将命令转换为 c_strings 数组(我们称之为 cmdarray),然后调用 dopiping(cmdarray, 0, 3)。程序到达行的那一刻:
dup2(fd[1], 1)
程序因收到 SIGPIPE 而终止。为什么我的管道坏了,我该如何解决?
【问题讨论】:
-
您确定您的意思是
"usr/bin/cat"而不是"/usr/bin/cat"? -
另外,您的程序有一个逻辑错误:在成功调用
exec后它将无法继续。你忘了fork吗? -
是的,我的意思是“/usr/......”。我是否使用 fork() 来避免逻辑错误?
-
如果您阅读manual page for
execl(3),您会看到它“用新的过程映像替换当前的过程映像”,并且该函数没有返回。您通常调用fork(2)来创建一个新进程来执行exec调用,这让您的主进程继续运行。 -
好吧,我在我的 dopiping() 函数中进行了分叉,让子进程从管道中读取数据并让父进程写入管道。我的管道还是坏了,所以我不知道它是否在工作。