Lab 8: Solution

We are in the middle of grading Lab 8. In the mean time, take a look at one possible solution below:

int main()
{
     // code removed for brevity         
        :
        :   
     } else {
    //  loop through each commands, setup pipes.
            int i;
            int fd[2*MAX_PIPE_LENGTH];
            for (i = 0; i < num_of_cmds; i++) {
                // for k cmds, there should be k-1 pipes.
                // the ith cmd reads from fd[2i-2], write to fd[2i+1].
                if (i < num_of_cmds - 1) {
                    pipe(&fd[2*i]);
                }
                pid = fork();
                int read_from = (i<<1)-2;
                int write_to  = (i<<1)+1;
                switch (pid) {
                    case -1: perror("fork"); exit(1);
                    case  0: 
                        if (i != 0) {
                            if (dup2(fd[read_from], STDIN_FILENO) == -1)
                                perror("dup2");
                            close(fd[read_from+1]);
                        } 
                        if (i != num_of_cmds-1) {
                            if (dup2(fd[write_to], STDOUT_FILENO) == -1)
                                perror("dup2");
                            close(fd[write_to-1]);
                        }
                        execvp(args[i][0], args[i]);
                        perror(args[i][0]);
                        close(fd[read_from]);
                        close(fd[write_to]);
                        exit(1);
                    default:
                        if (i > 0) {
                            if (close(fd[2*i-2]) == -1) {
                                perror("close");
                            }
                            if (close(fd[2*i-1]) == -1) {
                                perror("close");
                            }
                        }
                        break;
                }
            }
            for (i = 0; i < num_of_cmds; i++)
                waitpid(-1, NULL, 0);
        }
        free(command);
    }
    return 0;
}