2015-02-25 3 views
1

У меня возникла проблема с зависанием процесса. Я искал эту проблему и ее единственную ошибку, которую я имею в настоящее время для моей программы оболочки.программа застряла в ожидании()

Проблема заключается в том, что программа должна выйти, когда пользователь вводит «выход». Однако кажется, что если пользователь вводит недопустимую строку, программа застревает в wait(). это приводит к необходимости дважды вводить exit для выхода вместо одного. Как остановить это, как я могу выйти из вызова wait(), когда пользователь вводит тупицу?

Шагов для воспроизведения:

  • компилировать и запускать с GCC/G ++
  • типа в ругательстве вашего выбора
  • типа выход
  • уведомления о выходе из программы оленьей кожи (потому что его застряли на ожиданиях(), но подсказка
  • тип выход снова
  • программные выходы


#include <iostream> 
#include <unistd.h> 
#include "stdlib.h" 
#include "stdio.h" 
#include <iostream> 
#include <string> 
#include <sys/wait.h> 
#include <sstream> 
#include <cstring> 
#include <sys/types.h> 
#include <sys/stat.h> 

using std::string; 

using std::cout; 
using std::endl; 


bool exitstatus; 
int argsIndex = 0; 
pid_t pid; 
int main(void) 
{ 

    char * args[100]; 
    string check = "";   

    while(exitstatus==false) 
    { 
     cout<<"tinyshell:~>"; 
     std::getline(std::cin, check); 
     if(check == "exit"){ 
      exitstatus==true; 

     } 

     if(exitstatus==false&&check!="cd..") 
     { 
      pid = fork(); 
      perror(""); 
      if (pid < 0) { /* error occurred */ 
       fprintf(stderr, "Fork Failed"); 
       //return 1; 
      } 
      else if (pid == 0) { /* child process */ 
       execvp(args[0],args); 
       perror(""); 
      } 
      else if(check!= "&"){/* parent will wait for the child to complete */ 
       wait(NULL); 
       perror(""); 
       // cout <<"Child Complete" << endl; 
      } 
      else 
      { 
      } 
     } 
    } 
    return 0; 
}; 
+0

Вы делаете 'fork()', поэтому у вас может быть несколько процессов для завершения. И дочерний процесс наследует значение 'exitstatus'' false' на 'fork()' time, поэтому ему требуется отдельное закрытие. Попробуйте добавить 'getpid()' result в приглашение «tinyshell», чтобы посмотреть, с каким процессом вы разговариваете. – CiaPan

ответ

0

Это, возможно, придется сделать что-то с этой линии:

exitstatus==true; 

ли вам, случайно, означало:

existatus = true; 

gcc отчеты что-то подобное для это в любом случае (-Wall):

warning: statement has no effect [-Wunused-value] 
     exitstatus==true; 

Это довольно хороший пример, показывающий, почему включение предупреждений является хорошей практикой ...

Там также более тонкая проблема с вашим кодом. Вы не проверяете результат своей функции execvp. Поэтому в основном, если вы введете некоторую команду мусора в свою оболочку, ваш exec завершится неудачно, но ваш дочерний процесс продолжит выполнение того же кода, что и родительский (цикл).

Просто добавьте exit(EXIT_FAILURE); после вашего звонка execvp().

+0

Да, я видел это предупреждение при компиляции и его несвязанном виде, это воспроизводит ту же самую проблему im, что и в полной программе, которая компилируется без предупреждений. он, очевидно, используется, так как программа выходит из этого условия, хотя нет? Возможно, я не понимаю, что вы здесь пытаетесь сказать – Mars01

+0

@ Mars01. Мое последнее редактирование о вашем вызове 'execvp()' ... – dragosht

+0

edit: полностью непонятно – Mars01

Смежные вопросы