我想使用管道来重定向子进程的stdin和stdout。
目前我有以下代码:
void child(int pipeIn[], int pipeOut[]) {
char buff[20];
const char msg[]="Child Message\n";
close(pipeIn[1]);
close(pipeOut[0]);
if (dup2(pipeIn[0], 0))
perror("dup2 pipeIn");
if (dup2(pipeOut[1], 1))
perror("dup2 pipeOut");
close(pipeIn[0]);
close(pipeOut[1]);
for (int i = 0; i < 10; ++i) {
read(0, buff, 20);
fprintf(stderr, "Child: %s\n",buff);
printf("%s",msg);
}
}
void parent(int pipeIn[], int pipeOut[]) {
char buff[20];
const char msg[]="Parent Message\n";
close(pipeIn[0]);
close(pipeOut[1]);
for (int i = 0; i < 10; ++i) {
write(pipeIn[1], msg, 16);
read(pipeOut[0], buff, 50);
printf("Parent: %s", buff);
}
}
void test() {
int pipeOut[2],pipeIn[2];
if(pipe(pipeOut)) {
perror("pipeOut");
exit(1);
}
if(pipe(pipeIn)) {
perror("pipeIn");
exit(1);
}
int pid = fork();
if (pid == -1) {
perror("fork()");
exit(1);
}
else if (pid == 0)
child(pipeIn, pipeOut);
else
parent(pipeIn,pipeOut);
}
然而,这段代码无效,因为我一直在
dup2 pipeOut:未定义错误:0
最终陷入僵局 我知道代码停止了,因为父代一直在等待孩子的答案(永远不会到来)和孩子一直在等待从未到过的输入。
我不明白为什么我一直收到这个错误。难道我做错了什么?
我正在使用MacOS Lion 10.7.2和Xcode 4.2.1。
更新:在Adam Rosenfield的回答之后,我更正了我的if语句。然而,正如我所说的那样,代码仍然停止(我只能读出孩子打印Child: Parent Message
的第一件事而没有其他内容。
知道为什么会这样吗?
答案 0 :(得分:2)
dup2(2)
成功时返回一个非负整数,即新文件描述符。它出错时返回-1。在你的情况下,它在第一次调用时返回0,因为你正在将管道复制到文件描述符0上。
要解决此问题,请将支票从if(dup2(...))
更改为if(dup2(...) == -1)
。