вилки и трубы, что я делаю не так? - PullRequest
0 голосов
/ 15 октября 2019

Я пытаюсь узнать о каналах и перенаправлениях. Для этого я делаю несколько небольших программ, чтобы привыкнуть к соответствующим системным вызовам. На этом я пытаюсь запустить cat для файла pipe4.c и направить его вывод в grep, который я запускаю после. Это не работает, и я не понимаю результатов, хотя я думаю, что логика была хорошей, но я явно что-то упускаю с форком. Что я делаю не так?

Вот код:

    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #define BUFF_SIZE 4092

    //redirecting the output of a program ('cat' here)
    //to the stdin of another program ('grep' here)
    void    err_handler(char *msg)
    {
        perror(msg);
        exit(EXIT_FAILURE);
    }

    int main(void)
    {
        //creating a pipe to communicate between the child processes
        int p[2];
        if (pipe(p) < 0)
            err_handler("pipe error: ");
        /*
        ** forking for cat
        */
        pid_t cat_pid;
        if ((cat_pid = fork()) < 0)
            err_handler("fork error: ");
        if (cat_pid)
            close(p[1]);
        if (!cat_pid) {
            printf("===CAT===\n");
            dup2(p[1], STDOUT_FILENO);
            close(p[0]);
            close(p[1]);
            execl("/bin/cat", "cat", "pipe4.c", NULL);
            exit(EXIT_SUCCESS);
        }
        /*
        ** forking for grep
        */
        pid_t grep_pid;
        if ((grep_pid = fork()) < 0)
            err_handler("fork_error: ");
        if (grep_pid)
            wait(&grep_pid);
        if (!grep_pid) {
            printf("===GREP===\n");
            dup2(p[0], STDIN_FILENO);
            close(p[0]);
            close(p[1]);
            execl("/bin/grep", "grep", "\"err_handler\"", NULL);
            exit(EXIT_SUCCESS);
        }
        return 0;

}

Я получаю это только на своем терминале:

> pom@parrot ~/dev/19/syscall> sudo ./a.out 
> ===GREP===
> ===CAT===
> ===GREP===

Порядок, в котором эти строки печатаютсяменяется каждый раз, когда я его выполняю. Я ожидаю, что все строки, содержащие «err_handler» в моем файле pipe4.c, как если бы я делал это прямо в оболочке:

> pom@parrot ~/dev/19/syscall> cat pipe4.c | grep "err_handler"
> void  err_handler(char *msg)      err_handler("pipe error: ");
>       err_handler("fork error: ");            err_handler("creat error: ");
>               err_handler("read error: ");
>               err_handler("write error:");

1 Ответ

2 голосов
/ 15 октября 2019

Есть (я думаю!) 3 основных вопроса.

1) вы не используете ожидание правильно. Я бы посоветовал вместо этого использовать waitpid.

2) по крайней мере, в моей системе / bin / grep не существует. Это / usr / bin / grep. Но так как вы возвращаете EXIT_SUCCESS, когда exec не удается, вы не видите ошибки. Вам следует заменить execl (...); exit(EXIT_SUCCESS) на execl(...); perror("execl"); exit(EXIT_FAILURE);

3) Вы ищете буквальные кавычки. Это как если бы вы запустили:

grep '"err_handler"'

То есть аргумент execl при вызове grep должен быть "err_handler", а не "\"err_handler\""

...