2017-09-17 16 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 - 맥북 - 프로 : minish 엘리엇 $ ./minish

minish> LS

minish> 메이크 minish의 minish.cpp 시험

execv를 통해 ls를 실행 한 후 코드는 "minish>"를 인쇄하지 않고 더 많은 입력을 요구하지만 명령을 계속 입력하면 계속 실행할 수 있습니다 (예 : "ls").

이 문제의 원인은 무엇이며 어떻게 해결할 수 있습니까?

답변

2

내가 당신의 예를 따라 아주 확실하지 않다,하지만 당신은 fork() 잘못의 의미를 가질 수 있어야하므로 자식 프로세스는 pid == 1 또는 0이 없을 것 코드에서 반환 값이 1인지 확인하는 부모가 있습니다. 즉, 자식을 기다리지 않고 건너 뜁니다. 즉시 다른 반복을 계속합니다.

+0

오케이, pid> 0인지 확인하면 코드가 제대로 작동합니다. 고맙습니다! – ecatalano

0

하위 프로세스가 자체 출력을 완료하기 전에 프롬프트에 minish 프롬프트가 표시됩니다.

자식 프로세스에서 wait으로이를 방지 할 수 있습니다.

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 if(pid >= 0) /*instead of `if pid==1`*/ { 
    wait(NULL); 
}else { /*report fork failure */; }