Search code examples
cpipepthreadsfork

C Pipe Write and Read never hit EOF


I posted the issue with fork() and pipe(), but later I saw that the problem was only in pipe().

So I'm removing fork() code from here.

Problem: Writing in pipe(), and reading from pipe() but never reach the EOF condition in loops

Here is a simplification code of the problem:

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

int fd[2];

int main() {
    if(pipe(fd) == 0) {
        printf("Pipe is Open\n");
    }
    for(int i = 0; i < 5; i++) {
        close(fd[1]);
        write(fd[0], &i, sizeof(int));
        close(fd[0]);
    }
    for(int i = 0; i < 5; i++) {
        int value;
        close(fd[0]);
        read(fd[1], &value, sizeof(int));
        close(fd[1]);
        printf("%d\n", value);
    }
    return 0;
}

Output:

Pipe is Open
4
4
4
4
4

Solution

  • Had to use <fcntl.h> to work properly

    <fcntl.h> is a file control removed the need to close the pipe off my hands in order for it to reach EOF

    if (fcntl(fd[0], F_SETFL, O_NONBLOCK) < 0)
            exit(-1);
    

    Where fd[0] is the pipe created

    Without the fcntl() the code never hit the EOF condition

    The implementations below, unlike the previous code, the close() has been removed and the fcntl() has been added to handle this, giving the output as desired to read values ​​inside a pipe in a loop until reaching EOF.

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    int fd[2];
    int main() {
        if(pipe(fd) == 0) {
            printf("Pipe is Open\n");
        }
    
        if (fcntl(fd[0], F_SETFL, O_NONBLOCK) < 0)
            exit(-1);
        
        for(int i = 0; i < 5; i++) {
            write(fd[1], &i, sizeof(int));  
        }
        
        int status;
        while(1) {
            int value;
            status = read(fd[0], &value, sizeof(int));
            printf("status: %d\n", status);
             if(status > 0) {
                 printf("%d\n", value);
            } else {
                 // END of FILE
                 printf("\nEOF\n");
                 break;
            }
            
        }
        return 0;
    }
    

    OUTPUT:

    Pipe is Open
    status: 4
    0
    status: 4
    1
    status: 4
    2
    status: 4
    3
    status: 4
    4
    status: -1
    
    EOF