2013-10-08 2 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */ 

/** 
* setup() reads in the next command line, separating it into distinct tokens 
* using whitespace as delimiters. It also sets the args parameter as a 
* null-terminated string. 
*/ 

void setup(char inputBuffer[], char *args[],int *background) 
{ 
    int length, /* Number of characters in the command line */ 
     i,  /* Loop index for inputBuffer array */ 
     start, /* Index where beginning of next command parameter is */ 
     ct;  /* Index of where to place the next parameter into args[] */ 

    ct = 0; 

    /* Read what the user enters on the command line */ 
    length = read(STDIN_FILENO, inputBuffer, MAX_LINE); 

    start = -1; 
    if (length == 0) 
     exit(0);   /* ^d was entered, end of user command stream */ 
    if (length < 0){ 
     perror("error reading command"); 
    exit(-1);   /* terminate with error code of -1 */ 
    } 

    /* Examine every character in the inputBuffer */ 
    for (i = 0; i < length; i++) { 
     switch (inputBuffer[i]){ 
     case ' ': 
     case '\t' :    /* argument separators */ 
      if(start != -1){ 
       args[ct] = &inputBuffer[start]; /* set up pointer */ 
       ct++; 
      } 
      inputBuffer[i] = '\0'; /* add a null char; make a C string */ 
      start = -1; 
      break; 

     case '\n':     /* should be the final char examined */ 
      if (start != -1){ 
       args[ct] = &inputBuffer[start];  
       ct++; 
      } 
      inputBuffer[i] = '\0'; 
      args[ct] = NULL; /* no more arguments to this command */ 
      break; 

     case '&': 
      *background = 1; 
      inputBuffer[i] = '\0'; 
      break; 

     default :    /* some other character */ 
      if (start == -1) 
       start = i; 
    } 
    }  
    args[ct] = NULL; /* just in case the input line was > 80 */ 
} 

int main(void) 
{ 
    char inputBuffer[MAX_LINE]; /* Buffer to hold the command entered */ 
    int background;    /* Equals 1 if a command is followed by '&' */ 
    char *args[MAX_LINE/2+1];/* Command line (of 80) has max of 40 arguments */ 


    while (1){   /* program terminates normally inside setup */ 
    background = 0; 
    printf("CSE2431Sh->"); 
     fflush(0); 
     setup(inputBuffer, args, &background);  /* get next command */ 

     int child_pid; 
     int status; 

     child_pid = fork(); 

     if(child_pid == 0) 
     { 
       execvp(args[0],args); 
       /* If execvp returns, it must have failed. */ 

       printf("Execvp Failed\n"); 
       exit(0); 
     } 
     else 
     { 
       if(background == 0) 
       { 
         int parent_pid; 
         while ((parent_pid = wait(&status)) != -1 && parent_pid != child_pid) 
           ; 
       } 
       else 
       { 
         setup(inputBuffer, args, &background); 
       } 
     } 
    } 
} 

셸에 히스토리 기능을 추가하려고하는데 어떻게해야할지 모르겠다. 셸은 명령과 번호를 저장해야합니다. 또한 마지막 8 개 명령을 다시 실행하여 복구 할 수 있어야합니다. 예를 들어 사용자가 35 개의 명령을 입력 한 경우 28-35를 복구 할 수 있어야합니다. 사용자는 history를 입력하여 마지막 8 개의 명령을 볼 수 있어야하며 x num을 입력하여 이전 명령을 실행해야합니다. num은 명령 번호이거나 가장 최근 명령을 실행하는 xr입니다.간단한 쉘에 히스토리 기능 추가하기

+0

이 주제에 관해 구체적인 질문은 무엇입니까? 너 뭐 해봤 니? 무슨 일 했니? 무엇이 효과가 없었습니까? 어디서 붙어 있었 니? – pts

답변

2

linked list은 길이와 목록의 첫 번째 항목과 마지막 항목을 추가적으로 저장하는 것이 어떻습니까? 항목은 inputBuffer의 명령입니다.

+0

내가 로그인 한 이후로 오랜 시간이 걸렸지 만 이것이 내가 한 일입니다. – ab91

0

히스토리 명령의 경우 모든 입력 된 명령을 8 개 항목으로 제한되는 링크 된 목록에 저장하십시오. 9 개의 연결된 명령이 있으면 가장 오래된 명령을 삭제합니다.

당신은 프롬프트에서 표시하는 전역 변수 또는 증가 된 int 만 가질 수 있습니다.

희망이 도움이 될 수 있습니다!

관련 문제