试图用execp,dup2和pipe实现一个shell,挂起或“坏文件描述符”

时间:2014-02-10 21:34:52

标签: c++ shell pipe dup2

我正在尝试用c ++中的管道实现shell。我有命令工作,但一旦管道介入,事情就会停止工作。我会告诉你我的意思。这是代码:

    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轮俄罗斯轮盘赌。

无论如何,任何帮助表示赞赏。谢谢!

1 个答案:

答案 0 :(得分:0)

检查变量名称和参数, 其中一个值可能为NULL