2017-09-17 3 views
-2

Ich versuche, eine Shell in C++ zu implementieren, mit fork() und exec(). Mein Code ist wie folgt:Wie shell kontinuierlich nach Eingabe fragen nach execv in C++

#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; 
} 

Wenn ich diesen Code ausführen und versuchen, einen einzigen Befehl auszuführen, so scheint es richtig

Elliots-MacBook-Pro zu arbeiten: minish Elliot $ ./minish

minish> ls

minish> Make-Datei minish minish.cpp Test

Nach Ausführen von ls über execv, der Code nicht "Minish>", um mich für mehr Eingabe aufgefordert wird, ist jedoch in der Lage, kontinuierlich auszuführen, wenn ich weiterhin Befehle eingeben, d. H. "Ls".

Was ist die Ursache für dieses Problem, und wie kann ich es beheben?

Antwort

2

sein sollte Ich bin nicht ganz sicher, ob ich Ihrem Beispiel folgen, aber Sie haben die Semantik von fork() falsch:

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. 

Ihr Code überprüft, ob der Elternteil den Rückgabewert 1 anzeigt. Das bedeutet, dass er nicht auf das Kind wartet. es wird sofort mit einer weiteren Iteration fortgesetzt.

+0

Ahhhh okay, die Suche nach einem PID> 0 machte meinen Code richtig funktioniert. Vielen Dank! – ecatalano

0

Ihr Problem besteht darin, dass Sie die Eingabeaufforderung minish erhalten, bevor der untergeordnete Prozess seine eigene Ausgabe beendet.

Sie können dies durch wait in dem untergeordneten Prozess verhindern. Das Kind Prozess wird nie pid == 1 oder 0, so dass Ihre else-Klausel

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