C - 如何在只读取单个字符时检测管道中的EOF?

jir*_*lav 0 c pipe file-descriptor eof

正如回答中所解释的那样,在编写进程关闭所有相关文件描述符EOF之后,我期待读者进程能够正确捕获.

但这并没有发生,这个程序最终陷入无休止的循环.父母等待孩子完成,孩子等待发出EOF封闭管道的信号.

为什么读者进程没有收到EOF

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wait.h>

#define STRING_TO_SEND "Hello, world!\n"

int main() {
    int fd[2], i = 0;
    __pid_t pid;
    char _char;
    ssize_t nbytes;

    pipe(fd);
    pid = fork();

    if (pid == -1) {
        // Error
        perror("Error forking!");
        return EXIT_FAILURE;

    } else if (pid == 0) {

        // Child
        close(fd[1]);
        while ((nbytes = read(fd[0], &_char, 1)) != EOF) {
            if (nbytes == 0)
                continue;
            putchar(_char);
        }
        close(fd[0]);

    } else {

        // Parent
        close(fd[0]);

        for(;;) {
            _char = STRING_TO_SEND[i++];
            write(fd[1], &_char, 1);
            if (_char == '\0')
                break;
        }

        close(fd[1]);
        close(STDOUT_FILENO);

        while (wait(NULL)>0) {}
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

usr*_*usr 5

你只是误解了"文件结束"指示,read()其中只是意味着没有更多的东西可读read()(read()在这种情况下返回0).但read()实际上并没有返回 EOF.所以你的病情应该是:

while ((nbytes = read(fd[0], &_char, 1)) > 0) {
Run Code Online (Sandbox Code Playgroud)

也是__pid_tC库的内部类型.你不应该使用它; 只是用pid_t.

有关详细信息,请参阅read(2)的手册页.