2013-03-06 4 views
1

다른 쉘에서이 기본 쉘 프로그램을 실행하고 있습니다. "ls"실행 후 내 셸이 계속 실행되지 않는 이유를 알아낼 수 없습니다. 나는 그것을위한 종료가 없다. 그러나 그것은 원래의 쉘로 돌아 간다. 나는 그것을 사용할 때마다 매번 쉘 프로그램을 실행해야한다. 나는 포크가 무엇을 해야하는지를 알았다. 나는 if else 문으로 코딩 한 exit 명령을 사용하여 쉘을 종료하기 만하면됩니다. 어떤 제안이라도 대단히 감사 할 것입니다. 오, gettoks() 파서 함수를 무시하고 입력을 위해 사용하는 방법을 알아낼 수 없으므로 gettoks() 파서를 사용하는 대신 cmst 문자열 입력에 대한 else 문을 작성했습니다. 난에 입력을 전달하는 방법을 알아낼 수 없습니다 주로 때문에 당신이 의심으로명령 다음에 쉘을 계속 실행하는 방법

#include <iostream> 
#include <unistd.h> 
#include <sys/types.h> 
#include <errno.h> 
#include <signal.h> 
#include <cstdlib> 
#include <sys/wait.h> 

using namespace std; 
// Initializing counters for trapping 
static int cc_counter = 0; 
static int cz_counter = 0; 
static int cq_counter = 0; 
//Functions for trap signal handler 
void cc_handler(int signo) 
{ 
++cc_counter; 
} 
void cz_handler(int signo) 
{ 
++cz_counter; 
} 
void cq_handler(int signo) 
{ 
++cq_counter; 
} 

//********************************************************* 
// 
// Extern Declarations 
// 
//********************************************************* 
using namespace std; 
extern "C" 
{ 
extern char **gettoks(); 
} 


//********************************************************* 
// 
// Main Function 
// 
//********************************************************* 
int main(int argc, char *argv[]) 
{ 
// local variables 
int ii; 
char **toks; 
int retval; 

// initialize local variables 
ii = 0; 
toks = NULL; 
retval = 0; 
char buf[1000];//Initialize of size for current working directory 
string cmSTR;//String to hold input 
int status;//Initialization of status for fork() 
pid_t pid;//Declaration of pid 

// main (infinite) loop 
while(true) 
{ 
    signal(SIGINT, cc_handler);// Traps Ctrl+C 
    signal(SIGTSTP, cz_handler);// Traps Ctrl+Z 
    signal(SIGQUIT, cq_handler);// Traps Ctrl+\ 
    //prompt and show current working directory 
    cout <<("RS_SHELL:") << getcwd(buf,1000) << "\t"; 
    getline(cin ,cmSTR);//read input from keyboard 
    // if else loop to switch based on command input 
    if(cmSTR == "ls")// if ls, then execute arguement 
    { 
    execl("/bin/ls", "ls", NULL);//System call to execute ls 

    } 
    else if(cmSTR == "exit")//if exit, then execute block of code 
    { 
     cout << "Ctrl C entered: " << ++cc_counter << "times"<< endl; 
     cout << "Ctrl Z entered: " << ++cz_counter << "times"<< endl; 
     cout << "Ctrl Back Slash entered: " << ++cq_counter << "times"<< endl; 
     exit(1); 
     } 
    else if(cmSTR == "guish")// if guish, execute guish shell 
    { 
     execvp("guish", NULL); 
     } 
     //if input is not any of previous commands then fork() 
    else if(cmSTR != "ls" && cmSTR != "exit" && cmSTR != "guish" && cmSTR != "\n") 
    { 
     pid = fork(); 
     if (pid < 0)//Loop to fork parent and child process 
     { 
      fprintf(stderr, "Fork Failed"); 
      exit(-1); 
      } 
      else if (pid == 0)//Child process 
     { 
      execvp("guish", NULL);//system call to execute guish shell 

      } 
      else //Parent process 
      { 
       waitpid(-1, &status,0); 
       exit(0); 
       } 
       } 




    // get arguments 
    toks = gettoks(); 

    if(toks[0] != NULL) 
{ 
    // simple loop to echo all arguments 
    for(ii=0; toks[ii] != NULL; ii++) 
    { 
     cout << "Argument " << ii << ": " << toks[ii] << endl; 
    } 

    if(!strcmp(toks[0], "exit")) 
    break; 
} 
    } 

    // return to calling environment 
    return(retval); 
    } 

답변

0

, execl 및 관련 기능은 새로운 프로세스와 현재의 프로세스를 오버레이. 따라서 execl 호가 ls으로 시작되면 더 이상 프로그램이 계속 실행되지 않습니다. 당신이 당신의 쉘 프로그램이 ls을 실행 한 후 주위를 유지하려면

, 당신은 전화 execl("/bin/ls", "ls", NULL); 전에 fork()해야합니다.

의 출력을 쉘과 동일한 콘솔에 표시하려는 경우, 사용자가 의도 한 것일 수도 있으므로 ls의 출력을 사용자의 쉘로 파이프 한 다음 해당 출력을 다음과 같이 출력해야합니다. 쉘의 콘솔. 예를 들어 Writing my own shell… stuck on pipes?을 참조하십시오.

+0

if 문 외부에 있습니까? – user2125805

+0

예, 나는'if'의 각 경우에 대해 개별적으로 분기하지 않고'fork()'를하기 전에'fork()'를 할 것입니다 - DRY (자신을 반복하지 마십시오)는 좋은 모토입니다. – Simon

관련 문제