如何在C ++中执行execv之后不断要求shell输入

时间:2017-09-17 22:05:12

标签: fork posix child-process multiprocess waitpid

我正在尝试使用fork()exec()在c ++中实现shell。我的代码如下:

#include <iostream>
#include <string>
#include <unistd.h>
#include <sstream>
#include <vector>

using namespace std;

int main(int argc, char** argv){
    while(true){
        cout << "minish> ";
        string input = "";
        getline(cin, input);

        int count = 1;
        int shouldCount = 1;
        if(input.length() == 0) shouldCount = 0;

        if(shouldCount == 1){
            int didFindLetter = 0;
            for(int i = 1; i < input.length()-1;i++){
                if(input[i] ==' ' && didFindLetter == 1){
                    count++;
                    didFindLetter = 0;
                }
                else if(input[i]!=' '){
                    didFindLetter = 1;
                }
            }
        }

        //need to create a wordArray here...
        vector<string> wordArray;
        std::istringstream iss (input);
        string tempWord;
        for(int i = 0; i < count; i++){
            iss >> tempWord;
            wordArray.push_back(tempWord);
        }

        char* argsArray[1024];
        count = 0;
        for (int i = 0; i < wordArray.size(); i++) {
            //strdup returns pointer to a char array copy of its parameter
            argsArray[count++] = strdup(wordArray[i].c_str());
        }
        argsArray[count++] = (char *)NULL;


        pid_t pid = fork();

        if(pid == 0){
            //child
            execvp(argsArray[0], argsArray);
            fprintf(stderr, "exec: %s\n", strerror(errno));
            exit(errno);

        }
        else if(pid == 1){
            //int waitStatus;
            //pid_t terminated_child_pid = wait(&waitStatus);
            wait(NULL);
        }
    }

    return 0;
}

当我运行此代码并尝试执行单个命令时,它似乎正常工作

  

Elliots-MacBook-Pro:迷你Elliot $ ./minish

     

minish&GT; LS

     

minish&GT; makefile minish minish.cpp test

通过execv运行ls之后,代码不会打印“minish&gt;”来提示我输入更多内容,但是,如果我继续输入命令,即“ls”,则能够继续执行。

这个问题的原因是什么,我怎么能修复它?

2 个答案:

答案 0 :(得分:2)

我不太确定我是否遵循了您的示例,但您的语义为fork()错误:

RETURN VALUE
       On success, the PID of the child process is returned 
       in the parent, and 0 is returned in the child.  On
       failure, -1 is returned in the  parent, no child 
       process is created, and errno is set appropriately.

您的代码让父母检查返回值1 - 这意味着它会跳过等待孩子;它会立即继续进行另一次迭代。

答案 1 :(得分:0)

您的问题是,在子进程设法完成自己的输出之前,您正在获得minish提示。

您可以通过wait子进程来阻止此操作。子进程永远不会有pid == 10,因此您的else子句应该是

else if(pid >= 0)  /*instead of `if pid==1`*/ {
    wait(NULL);
}else { /*report fork failure */; }