Jeff
Jeff

Reputation: 337

Two-Way Parent Child Communication Using 2 Pipes in C on Linux

I'm trying to create a two-way communication between parent and child processes using 2 pipes using C on Linux. The parent is my program and the child is just a random program (say "cat").

I try to uses read() in parent to read child output, but it gives me errno 9, which is Bad file descriptor.

The following is my code

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

#define Read            0
#define Write           1
#define ParentRead      read_pipe[1]
#define ParentWrite     write_pipe[0]
#define ChildRead       write_pipe[1]
#define ChildWrite      read_pipe[0]

int main()
{
    int data_processed;

    /** Pipe for reading for subprocess */
    int read_pipe[2];
    /** Pipe for writing to subprocess */
    int write_pipe[2];

    char buffer[100];
    memset(buffer, '\0', 100);

    if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
    {
        pid_t pid = fork();
        if (pid == (pid_t)-1)
        {
            fprintf(stderr, "Fork failure");
            exit(EXIT_FAILURE);
        }
        else if (pid == (pid_t)0) //Child process
        {
            close(Read);
            close(Write);
            close(ParentRead);
            close(ParentWrite);
            dup(ChildRead);
            dup(ChildWrite);
            execlp("cat", (char*)NULL);
            exit(EXIT_FAILURE);
        }
        else { //Parent process
            close(ChildRead);
            close(ChildWrite);

            write(ParentWrite, "abc", 3);
            int r = read(ParentRead, buffer, 99);
            printf("%d %d", r, errno);
            puts(buffer);
        }
    }

    exit(EXIT_SUCCESS);
}

Upvotes: 4

Views: 18637

Answers (2)

mikithskegg
mikithskegg

Reputation: 816

If you want to redirect stdin and stdout to pipes, you need to use dup2(2) system call.

dup2 (ChildRead, 0);
dup2 (ChildWrite, 1);

P.S. Also I found wrong directions of reading/writing in pipes. Here is the correct way

#define ParentRead      read_pipe[0]
#define ParentWrite     write_pipe[1]
#define ChildRead       write_pipe[0]
#define ChildWrite      read_pipe[1]

Remember: pipe[0] is fd for reading, pipe[1] is fd for writing.

And one more error, in execlp. Do not forget to set the first argument you send to the executed programm as a name of the program

execlp("cat", "cat", (char*)NULL);

Upvotes: 3

tbert
tbert

Reputation: 2097

What happens if you just perform a read/write? I'm unsure that dup and cat are what you want here, to be honest:

char buf[256];
int len;

len = read(ChildRead, 256);
write(ChildWrite, len);

And, thinking further, if you know the fd you want to end up at, use dup2, not dup. Know your APIs, people!

And, thinking even further, you could look at the source for the popen(3) call, which does exactly this, in a more general way.

Upvotes: 0

Related Questions