Простая оболочка: обработка труб приводит к бесконечному циклу - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь передать трубы с функцией ниже, но это приводит к бесконечному циклу.Мой код основан на этом: Реализация нескольких каналов в C .

Я новичок в C, поэтому буду признателен за любые мысли или отзывы об этом решении.Пожалуйста, дайте мне знать, если потребуется какая-либо другая информация.Больше нет бесконечного цикла, если я уберу третий оператор if, поэтому проблема где-то здесь.

void command_with_pipes(char*** command_table, int count_pipes, bool converted_to_tee) {
    int fd[2 * count_pipes];
    pid_t pid; 
    int status; 

    // Create all necessary pipes at the beginning 
    for (int i = 0; i < count_pipes; i++) {
        if (pipe(fd + i*2) < 0) {
            perror("fatal error: pipe");
            exit(1);
        }
    }

    // Iterate over every command in the table 
    for (int commandNum = 0; commandNum <= count_pipes; commandNum++){
        pid = fork(); 
        if (pid < 0){
            perror("fork error"); 
            exit(-1);
        }

        else if (pid == 0){
            // If it's not the first command, should read to the pipe 
            if (commandNum != 0) {
                if(dup2(fd[(commandNum - 1) * 2], 0) < 0) {
                    perror("2 can't dup");
                    exit(1);
                }
            }

            // if not the last command, should write to the pipe 
            if (commandNum != count_pipes) {
                if(dup2(fd[commandNum  * 2 + 1], 1) < 0) {
                    perror("1 can't dup");
                    exit(1);
                }
            }

            // Last command includes a converted tee, should write to pipe instead of going to standard output 
            if (commandNum == count_pipes && strcmp(command_table[commandNum][0], "tee") ==0 && converted_to_tee == true){
                if(dup2(fd[(commandNum - 1) * 2 + 1], 1) < 0) {
                    perror("1 can't dup");
                    exit(1);
                }
            }

            // Close pipes 
            for (int i = 0; i < 2 * count_pipes; i++){
                close(fd[i]);
            }

            // Execute the command 
            status = execvp(command_table[commandNum][0], command_table[commandNum]);
            if (status < 0) {
                perror("exec problem");
                exit(1);
            }
        }
    }
    // Parent closes everything at the end 
    for (int i = 0; i < 2 * count_pipes; i++){
        close(fd[i]);
    }
    wait(0);
}
...