Unix Piping с использованием Fork и Dup - PullRequest
2 голосов
/ 07 апреля 2010

Допустим, в моей программе я хочу выполнить два дочерних процесса, один для выполнения команды "ls -al", а затем передать ее в команду "wc" и отобразить вывод на терминале. Как я могу сделать это, используя дескрипторы файла канала на данный момент код, который я написал: Пример будет очень полезным

int main(int argc, char *argv[]) {
    int pipefd[2];
    int pipefd2[2];

    pipe(pipefd2);
    if ((fork()) == 0) {
       dup2(pipefd2[1],STDOUT_FILENO);
       close(pipefd2[0]);
       close(pipefd2[1]);
       execl("ls", "ls","-al", NULL);
       exit(EXIT_FAILURE);
    } 

    if ((fork()) == 0){
        dup2(pipefd2[0],STDIN_FILENO);
        close(pipefd2[0]);
        close(pipefd2[1]);
        execl("/usr/bin/wc","wc",NULL);
        exit(EXIT_FAILURE);
    }
    close(pipefd[0]);
    close(pipefd[1]);
    close(pipefd2[0]);
    close(pipefd2[1]);
}

1 Ответ

10 голосов
/ 07 апреля 2010

Ваш пример кода был синтаксически и семантически нарушен (например, pipefd2 не уничтожен, путаница между pipefd и pipefd2 и т. Д.) Поскольку это пахнет домашней работой, пожалуйста, убедитесь, что вы понимаете мои аннотации ниже и спросите больше, если вам нужно.Я пропустил проверки ошибок на pipe, fork и dup, но они должны быть там, в идеале.

int main(int argc, char *argv[]) {
    int pipefd[2];
    pid_t ls_pid, wc_pid;

    pipe(pipefd);

    // this child is generating output to the pipe
    //
    if ((ls_pid = fork()) == 0) {
        // attach stdout to the left side of pipe
        // and inherit stdin and stdout from parent
        dup2(pipefd[1],STDOUT_FILENO);
        close(pipefd[0]);              // not using the right side

        execl("/bin/ls", "ls","-al", NULL);
        perror("exec ls failed");
        exit(EXIT_FAILURE);
    } 

    // this child is consuming input from the pipe
    //
    if ((wc_pid = fork()) == 0) {
        // attach stdin to the right side of pipe
        // and inherit stdout and stderr from parent
        dup2(pipefd[0], STDIN_FILENO);

        close(pipefd[1]);              // not using the left side
        execl("/usr/bin/wc", "wc", NULL);
        perror("exec wc failed");
        exit(EXIT_FAILURE);
    }

    // explicitly not waiting for ls_pid here
    // wc_pid isn't even my child, it belongs to ls_pid

    return EXIT_SUCCESS;
}
...