alaamh
alaamh

Reputation: 983

Multi Forks controlled by main parent pipe

I have this code, it work fin but if i change NUM_CHILDREN = 2 or any other number "not equal 1" it bad file descriptor. why is that?

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

enum {
    NUM_CHILDREN = 1
};

static int pipes[NUM_CHILDREN][2];

void start_encoding(void) {
    pid_t d, h;

    int pipe_master[2];
    pipe(pipe_master);
    if (d = fork()) {
        int j;
        for (j = 0; j < NUM_CHILDREN; j++) {
            int pipe_sub[2];
            pipe(pipe_sub);
            pipes[j][0] = pipe_sub[0];
            pipes[j][1] = pipe_sub[1];
            if (h = fork()) {
                dup2(pipes[j][0], 0);
                close(pipe_master[0]);
                close(pipe_master[1]);
                for (j = 0; j < NUM_CHILDREN; j++) {
                    close(pipes[j][0]);
                    close(pipes[j][1]);
                }
                execl("/bin/sort", "sort", NULL);
            } else {
                close(STDIN_FILENO);
                dup2(pipe_master[0], STDIN_FILENO);
                close(STDOUT_FILENO);
                dup2(pipes[j][1], STDOUT_FILENO);
                close(pipe_master[0]);
                close(pipe_master[1]);
                for (j = 0; j < NUM_CHILDREN; j++) {
                    close(pipes[j][0]);
                    close(pipes[j][1]);
                }
                execl("/bin/sed", "sed", "s/tty/TTY/g", NULL);
            }
        }
    } else {
        close(STDOUT_FILENO);
        dup2(pipe_master[1], STDOUT_FILENO);
        close(pipe_master[0]);
        close(pipe_master[1]);
        execl("/usr/bin/who", "who", NULL);
    }
} 

Actually i want to simulate:

             -- sed
        |---|
        |    -- sort
  who --|
        |    -- sed
        |---|
        |    -- sort
        |
         --- ...

what should i use?

Upvotes: 0

Views: 965

Answers (2)

David Gelhar
David Gelhar

Reputation: 27900

This code:

    for (j = 0; j < NUM_CHILDREN; j++) {
...
      if (h = fork()) {
...
            for (j = 0; j < NUM_CHILDREN; j++) {
                close(pipes[j][0]);
                close(pipes[j][1]);
            }
            execl("/bin/sort", "sort", NULL);

Is going to attempt to close pipes that have not yet been opened (if NUM_CHILDREN > 1)

Use of the same loop variable (j) for the inner and outer loops is a problem too.

Another issue is that you are doing the execl("/bin/sort") from the parent, so the outer loop is never going to get past the first iteration.

Upvotes: 0

caf
caf

Reputation: 239041

Because in these nested loops:

for (j = 0; j < NUM_CHILDREN; j++) {
    close(pipes[j][0]);
    close(pipes[j][1]);
}

You're trying to close file descriptors that you haven't created yet. You also can't re-use j here - you need a different variable for these inner loops.

Upvotes: 1

Related Questions