Попытка реализовать оболочку с execp, dup2 и pipe, зависаниями или «плохим дескриптором файла»

0

Я пытаюсь реализовать оболочку с трубопроводом в c++. У меня есть команды, работающие, но как только трубы становятся вовлеченными, все перестает работать. Я покажу вам, что я имею в виду. Здесь код:

    int inPipe[2];
    int outPipe[2];
    pipe(inPipe);
    pipe(outPipe);

    int std_in = dup(0);
    int std_out = dup(1);
    std::for_each(cmds.begin(), cmds.end(), [&](Command command){
        //printf("Executing [%s] \n", command.args[0].c_str());
        auto pid = fork();
        if(pid==-1) {
            std::cerr << "Could not fork\n";
            return;
        }
        if (pid==0) {
            //std::cout << "Child\n";

            if(command.inFile == "none") {
                printf("In, none.\n");
                dup2(std_in, 0);
                close(std_in);
            }
            else if(command.inFile == "pipe") {
                printf("In, pipe.\n");
                dup2(inPipe[0], 0);
                close(inPipe[0]);
            }

            if(command.outFile == "none") {
                printf("Out, none.\n");
                dup2(std_out, 1);
                close(std_out);
            }
            else if(command.outFile == "pipe") {
                printf("out, pipe.\n");
                dup2(outPipe[1], 1);
                close(outPipe[1]);
            }

            const char* name = command.args[0].c_str();
            char** args = new char*[command.args.size()];
            for(int i=0; i<command.args.size(); i++) {
                args[i] = new char[command.args[i].size()];
                strcpy(args[i], command.args[i].c_str());
            }

            execvp(name, args);
            exit(errno);
        }
        else {
            //std::cout << "Parent\n";
            int status;
            auto before = std::chrono::system_clock::now();

            dup2(outPipe[0], inPipe[0]);
            dup2(outPipe[1], inPipe[1]);
            close(outPipe[0]);
            close(outPipe[1]);
            pipe(outPipe);

            waitpid(pid, &status, 0);


            auto after = std::chrono::system_clock::now();
            std::chrono::duration<double> ptime = after-before;
            elapsed_time = elapsed_time + ptime.count();
        }
    });

Когда я запускаю команды с одним каналом, как простой "ls", он отлично работает. Однако, если я использую ls | sort, он дает это сообщение об ошибке:

ls: cannot access : No such file or directory

и затем зависает, пока я не оттуда. Я думаю, что зависание происходит от меня, когда-то неправильно меняют трубы (не закрывая их), но я не знаю, где и сколько раз, чтобы вставить это. Я думаю, что "не может получить доступ" происходит от того, что я теряю std_in перед тем, как позвонить Как-то. Я новичок в почти всех этих функциях (dup2, fork, execp, pipe и т.д.), Поэтому я чувствую, что мое предположение и проверка больше похожи на рулетку с 6 раундами.

В любом случае, любая помощь приветствуется. Благодарю!

Теги:
pipe
dup2

1 ответ

0

Проверьте переменные Name и Args, одно из этих значений может быть NULL

Ещё вопросы

Сообщество Overcoder
Наверх
Меню