execv, трубы, dup для ls и grep не работают - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть следующий код, который должен выполнить следующую операцию

ls | grep txt

Он должен перечислить файлы с txt в именах файлов.

код с использованием pipe, fork, и execv is как показано ниже, но это не работает. Я создаю 2 процесса ls и grep из основного процесса и пытаюсь передать вывод ls в grep с помощью fds.

Я не могу выяснить, почему он не работает.

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <vector>

using namespace std;

void printerror(const char *str)
{
    std::string errorstr(str);
    errorstr.append(" Status ");
    perror(errorstr.c_str());
}

void operate_fds(int pass_fd, int close_fds[], int no_of_close_fds)
{
    for (size_t i = 0; i < no_of_close_fds; i++)
    {
        close(close_fds[i]);
    }
    dup(pass_fd);
    close(pass_fd);
}

pid_t create_child(char *const args[], int pass_fd, int close_fds[], int no_of_close_fds)
{
    pid_t child_pid = -1;

    // Create child process
    child_pid = fork();

    if(child_pid == 0) {
        cout << "In child Process args: " << args[0] << " pid: " <<  getpid() << "\n";
        operate_fds(pass_fd, close_fds, no_of_close_fds);
        execv(args[0],args);
        exit(0);
    }
    return child_pid;
}

int main(int argc, char *argv[])
{
    pid_t child_pid[2];
    pid_t wait_pid = -1;
    int terminated_cnt = 0;
    int pipe_descriptor[2];
    int close_fds[2];

    int ret = pipe(pipe_descriptor);

    cout << "Pipe creation " << (!ret ? "success":"failed") << "\n";
    printerror("Pipe returned") ;

    cout << "In main Process: "  <<  getpid() << "\n";

    // Create ls child process
    char *list_process_params[4];
    list_process_params[0] = "/bin/ls";
    list_process_params[1] = "-l";
    list_process_params[2] = NULL;

    close_fds[0] = STDOUT_FILENO;
    close_fds[1] = pipe_descriptor[0];
    child_pid[0] = create_child(list_process_params, pipe_descriptor[1], close_fds, 2);


    // Create grep child process
    char *grep_process_params[5];
    grep_process_params[0] = "/bin/grep";
    grep_process_params[1] = "txt";
    grep_process_params[2] = NULL;

    close_fds[0] = STDIN_FILENO;
    close_fds[1] = pipe_descriptor[1];
    child_pid[1] = create_child(grep_process_params, pipe_descriptor[0], close_fds, 2);

    // Wait for both the processes to terminate
    do{
        wait_pid = wait(NULL);
        if(wait_pid == child_pid[0] || wait_pid == child_pid[1]) {
            ++terminated_cnt;
        }
        cout << "Child process " << wait_pid << " terminated\n";
    }while(terminated_cnt < 2);

}

Пожалуйста, дайте мне знать, что не так с этим кодом

...