2016-02-02 70 views
1

问题是,该程序将不会输出预期的STARTEND,除非我将其从shell中删除,否则它也不会退出。Unix管道实验挂起

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include <string.h> 
#include <unistd.h> 

void check(bool b, const char *cp) { 
    if (!b) { 
     perror(cp); 
     exit(EXIT_FAILURE); 
    } 
} 

int main(void) { 
    int fd[2]; 
    check(pipe(fd) != -1, "pipe"); 
    pid_t pid = fork(); 
    check(pid != -1, "fork"); 
    if (pid == 0) { 
     check(dup2(1, fd[1]) != -1, "dup2"); 
     check(execlp("ls", "ls", NULL) != -1, "execlp"); 
    } else { 
     char cs[10000]; 
     read(fd[0], cs, sizeof cs); 
     printf("START\n%s\nEND\n", cs); 
    } 
    return EXIT_SUCCESS; 
} 

回答

4

你有DUP2的顺序(existing_fd,new_fd)逆转参数。

你有另一个bug,打破许多“让我们尝试管道(2)”实验。你没有关闭在叉子上重复的管道的末端。这通常会导致不同类型的挂起,因为读者不会看到EOF,因为读者进程具有管道的作者端的额外副本,所以仅关闭作者进程的结束部分并不足以给读者一个EOF。

因此,获得的习惯:

if (pid == 0) { 
    check(dup2(fd[1], 1) != -1, "dup2"); 
    close(fd[1]); // Here! 
    close(fd[0]); // ...and here! 
    check(execlp("ls", "ls", NULL) != -1, "execlp"); 
} else { 
    char cs[10000]; 
    close(fd[1]); // and here! 
    ... 
}