2017-09-17 8 views
-2

fork()exec()を使って、C++でシェルを実装しようとしています。次のように私のコードは次のとおりです。C++でexecvの後にシェルが入力を要求する方法

#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は動作するようです:minishエリオット$ ./minish

minish> LS

minish>メイクファイルminishのminish.cpp試験

execvでlsを実行した後、コードは "minish>"を表示して入力を促しますが、コマンドを入力し続けると継続的に実行できます。つまり "ls"です。

この問題の原因は何か、どのように修正できますか?

答えて

2

私は私はあなたの例に従っかなりわからないんだけど、あなたはfork()間違ったのセマンティクスを持つべきであるように、子プロセスは、pid == 1または0持つことは決してありませんあなたのコードは返り値1を親がチェックしています。つまり、子を待つことをスキップします。直ちに別の反復を続けます。

+0

大丈夫、pid> 0であることを確認することで、コードが正常に動作するようになりました。ありがとうございました! – ecatalano

0

子プロセスが自身の出力を終了する前に、minishプロンプトが表示されています。

子プロセスでこれを防ぐことができます。

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. 

:あなたのelse節が

else if(pid >= 0) /*instead of `if pid==1`*/ { 
    wait(NULL); 
}else { /*report fork failure */; } 
関連する問題