LostBoy
LostBoy

Reputation: 958

Fread blocks eternally on redirected stdout with named pipes

We are trying to communicate between two processes via named pipes that are redirected to stdin and stdout in the child process. The parent process opens the named pipe and calls fdopen on them. The problem we see is that fwrite on this works, however even reading one byte from redirected stdout pipe blocks eternally. The code works when using the file descriptors instead of FILE *. What is wrong? Code is a little long, sorry.

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

int create_fifo()
{
    int file1;
    unlink("fifo-0.0");
    file1 = mkfifo("fifo-0.0",0666); 
    if(file1<0) {
        printf("Unable to create a fifo");
        return 0;
    }
    unlink("fifo-0.1");
    file1 = mkfifo("fifo-0.1",0666); 
    if(file1<0) {
        printf("Unable to create a fifo");
        return 0;
    }
    return 1;
}

int main()
{
    int fd, fd0, fd1;
    pid_t pid;
    char read_buf_p[50],write_buf_p[50];
    char * args[3];
    FILE *fd_stdin_p, *fd_stdout_p;

    create_fifo();
    args[0] = "/bin/cat";
    args[1] = "-n";
    args[2] = NULL;

    pid = fork();
    if(pid == 0)
    {   
        fd = open("fifo-0.0", O_RDONLY);
        dup2(fd, 0);
        close(fd);
        fd = open("fifo-0.1", O_WRONLY);
        dup2(fd, 1);
        close(fd);
        execv(args[0],args);
    }
    else
    {
        fd0 = open("fifo-0.0", O_WRONLY);
        fd_stdin_p = fdopen(fd0,"w");
        fd1 = open("fifo-0.1", O_RDONLY);
        fd_stdout_p = fdopen(fd1,"r");
        int sz = fwrite("Hello World", sizeof(char), strlen("Hello World"), fd_stdin_p);
        fread(read_buf_p,1,1,fd_stdout_p);
        printf("%s\n", read_buf_p);
    }
    return 0;
}

Upvotes: 1

Views: 1027

Answers (2)

unwind
unwind

Reputation: 400029

This is the result of FILE-based I/O being "line-buffered", by default. This means that it reads and writes whole lines, and since your data isn't a whole line, it's stuck in the buffer and not passed through to the underlying file descriptor.

Try adding \n at the end of the output data, or call fflush().

Upvotes: 0

user2531540
user2531540

Reputation:

I think its because of buffering of Standard output. Just use '\n' at the end of fflush()

Upvotes: 1

Related Questions