Почему этот код останавливается при вызове./prog ls ls wc 1.txt?

При компиляции этого кода и вызове

./prog ls ls wc 1.txt

(должно быть

(ls; ls) | wc > 1.txt

этот код останавливается и выполняется только после Control-d. В чем дело?

#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    int fd[2];
    pipe(fd);
    if (!fork()) {
        close(fd[0]);
        dup2(fd[1], 1);
        close(fd[1]);
        if (!(fork())) {
            execlp(argv[1], argv[1], NULL);
            _exit(1);
        }
        wait(NULL);
        if (!fork()) {
            execlp(argv[2], argv[2], NULL);
            _exit(1);
        }
        wait(NULL);
    }
    close(fd[1]);
    wait(NULL);
    if (!fork()) {
        dup2(fd[0], 0);
        close(fd[0]);
        int ffd = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0600);
        dup2(ffd, 1);
        close(ffd);
        execlp(argv[3], argv[3], NULL);
        _exit(1);
    }
    close(fd[0]);
    wait(NULL);
    return 0;
}

1 ответ

Решение

Вы должны выйти из программы в первом дочернем процессе, в противном случае и исходный процесс, и дочерний процесс выполняют код внизу, который выполняется wc чтение из трубы.

Или вы можете поместить весь этот код в else блок, поэтому он не запускается в дочернем процессе.

#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    int fd[2];
    pipe(fd);
    if (!fork()) {
        close(fd[0]);
        dup2(fd[1], 1);
        close(fd[1]);
        if (!(fork())) {
            execlp(argv[1], argv[1], NULL);
            _exit(1);
        }
        wait(NULL);
        if (!fork()) {
            execlp(argv[2], argv[2], NULL);
            _exit(1);
        }
        wait(NULL);
    } else {
        close(fd[1]);
        wait(NULL);
        if (!fork()) {
            dup2(fd[0], 0);
            close(fd[0]);
            int ffd = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0600);
            dup2(ffd, 1);
            close(ffd);
            execlp(argv[3], argv[3], NULL);
            _exit(1);
        }
        close(fd[0]);
        wait(NULL);
        return 0;
    }
}
Другие вопросы по тегам