tags:

views:

79

answers:

2

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?

+1  A: 

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.

caf
A: 

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.

David Gelhar
if you don't mind, can you show me the road to do it correctly.
alaamh