2013-10-08 148 views
-2
#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. 
*/ 

typedef struct list 
{ 
    int num; 
    int *ptr; 
    struct history * next; 
}history; 

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 */ 

    /* the steps are: 
    (1) fork a child process using fork() 
    (2) the child process will invoke execvp() 
    (3) if background == 0, the parent will wait, 
     otherwise returns to the setup() function. */ 

     int child_pid; 
     int status; 
     int ph; 
     history *history = NULL; 

     child_pid = fork(); 

     if(child_pid == 0) 
     { 
       ph++; 
       history->num = ph; 
       history->ptr = args; 
       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_$ 
           ; 
       } 
       else 
       { 
         setup(inputBuffer, args, &background); 
       } 
     } 
    } 
} 

我試圖將歷史功能添加到外殼。 shell應該存儲命令並編號。它也應該能夠恢復最後的8個命令以再次運行。例如,如果已經由用戶28-35輸入了35個命令應該能夠被恢復。用戶應該能夠通過鍵入history來查看最後8個命令,並通過鍵入x num來運行前一個命令,其中num是命令編號,或者xr運行最近的命令。我的計劃是使用一個鏈表,但我遇到了麻煩,沒有幾個小時才能完成它。將歷史功能添加到外殼

+0

您對這項任務有什麼問題?你的問題越具體,你就可以有更好的機會幫助你。 – simonc

+1

「[你]沒有幾個小時才能完成」?具體編程問題的答案不是時間依賴性的。如果鏈接列表是正確的答案,那麼現在就是這個正確的答案,並且在六個月之後。 –

+1

如果要保存在歷史記錄中的命令數有固定的數字,可以使用數組。當索引到達數組的末尾時,將其包裝到開頭。沒有列表或指針需要。 Google循環緩衝區。 –

回答

0

正如我們在您的previous post推薦:

怎麼樣linked list,你還存儲長度,第一 和最後一個項目列表?這些項目是來自您的 inputBuffer的命令。

+0

如果您查看已添加的代碼,我嘗試了鏈接列表。我無法完成它 – ab91

+0

這不是'鏈接列表'的完整實現,[這裏](http://www.cprogramming.com/tutorial/c/lesson15.html)是一個教程的鏈接,將幫你。 – HappyDump