Darrel Holt
Darrel Holt

Reputation: 910

Unidirectional pipes in C

I'm having trouble trying to work out how to make individual pipes for a parent process and a child process to act in a unidirectional fashion. I.e.: a descriptor for the parent and a different descriptor for its child.

Here's what I have:

#include <sys/types.h>

int main(int argc, char *argv[]) {

    int parent[2];
    int child[2];
    pid_t pid;

    int num = 0;

    pipe(parent);
    pipe(child);

    pid =fork();

    if(pid > 0){ // do parent stuff

        num = 5;

        write(parent[1], &num, sizeof(num));
        printf("Parent with pid %d sent value: %d\n", getpid(), num);

        close(parent[1]);

    }else{ // do child stuff

        read(child[0], &num, sizeof(num));
        printf("Child with pid %d received value: %d\n", getpid(), num);

        close(child[0]);

        exit(0);
    }
    return 0;
}

The output:

Parent with pid 31702 sent value: 5

I know I'm supposed to close some of the descriptors at some point in there before the read() and write() commands, but it seems no matter what I close either the child response prints before the parent can write() or I end up with a broken pipe. Where should I close the descriptors to successfully use these pipes unidirectionally?

Upvotes: 0

Views: 1513

Answers (2)

hobbs
hobbs

Reputation: 239881

You're making two pipes and then only using one end of each of them; the communication doesn't work because nobody is paying any attention to the other end of either. parent and child are totally independent pipes, what you send on one doesn't appear on the other. You only need one pipe:

int main(int argc, char *argv[]) {

    int pipefd[2];
    pid_t pid;

    int num = 0;

    pipe(pipefd);

    pid = fork();

    if(pid > 0){ // do parent stuff
        close(pipefd[0]); // close the reading end

        num = 5;

        write(pipefd[1], &num, sizeof(num)); // write on the writing end
        printf("Parent with pid %d sent value: %d\n", getpid(), num);

    }else{ // do child stuff
        close(pipefd[1]); // close the writing end

        read(pipefd[0], &num, sizeof(num)); // read on the reading end
        printf("Child with pid %d received value: %d\n", getpid(), num);

        exit(0);
    }
    return 0;
}

A pipe is already unidirectional, and it gives you two ends back: a writing end and a reading end. You just have to use each one appropriately.

Upvotes: 1

ffff
ffff

Reputation: 3070

In a nutshell, that's not how you should work with pipes.

A pipe has a read 0 and write 1 end.

In your case, the child is reading from child[0], but nobody is going to write to the child through child[1]. The parent is going to write to the parent[1].

Try using a single pipe (change child[0] to parent[0]). And make sure you delete the ends you wont be using in the respective processes

Upvotes: 1

Related Questions