2017-03-01 61 views
0

我想做一個shell「bosh>」,它需要在Unix命令並不斷收到錯誤的地址錯誤。我知道我的代碼讀取命令並解析它們,但出於某種原因,我無法讓它們執行,而是出現「錯誤地址」錯誤。與execvp錯誤的地址錯誤

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <sys/types.h> 
#include <string.h> 
#include <sys/wait.h> 
#define MAX_LINE 128 
#define MAX_ARGS 10 



int main(){ 
    pid_t pid; 
    char command[MAX_LINE]; /*command line buffer*/ 
    char *commandArgs[MAX_ARGS]; /*command line arg*/ 
    int i; 
    char *sPtr=strtok(command," "); 
    int n=0; 


    printf("bosh>"); 
    fgets(command, MAX_LINE-1,stdin); 
    command[strlen(command)-1]='\0'; 


    while(strcmp(command,"quit")!=0) 
    { 
     n=0; 

     sPtr=strtok(command," "); 
     while(sPtr&&n<MAX_ARGS) 
     { 
      sPtr=strtok(NULL," "); 
      n++; 
     } 

     commandArgs[0]=malloc(strlen(command)+1); 
     strcpy(commandArgs[0],command); 

     if(fork()==0) 
     { 
      execvp(commandArgs[0],commandArgs); 
      perror("execvp failed"); 
      exit(2); 
     } 
     pid=wait(NULL); 


     printf("%s",">"); 
     fgets(command, MAX_LINE-1,stdin); 
     command[strlen(command)-1]='\0'; 
    } 

    printf("Command (%d) done\n", pid); 

    return 0; 


} 
+0

首先,圖片中的好狗。 終止空字節('\ 0')存儲在由'fgets'讀取的緩衝區中的最後一個字符之後。所以你不需要放一個''\'0'。 –

+0

@TonyTannous即剝離換行符(儘管它也不正確)。 –

+0

你想檢查最後一個字符確實是一個''\ n''在切斷它之前。 –

回答

3

這兩條線是罪魁禍首:

所有的
commandArgs[0]=malloc(strlen(command)+1); 
strcpy(commandArgs[0],command); 

首先,malloc(strlen(...))其次strcpy是什麼POSIX功能strdup已經這樣做了。但是,你並不需要,甚至複製字符串 - 這是不夠的,只是指針原始字符串存儲到commandArgs[0]

commandArgs[0] = command; 

不過,如何做execvp多少參數的命令是要採取?如果你仔細閱讀手冊,他們會這樣說:

execv()execvp()execvpe()函數提供的指針表示可用於新程序的參數列表空值終止字符串數組。按照慣例,第一個參數應指向與正在執行的文件關聯的文件名。 指針數組 MUST 由NULL指針終止。

您的參數數組不是NULL結尾。要修復它,用

commandArgs[0] = command; 
commandArgs[1] = NULL; // !!!! 

(然後你會發現,你預期的要分配的參數strtok解析循環,這樣就可以實際分配所有的參數到commandArgs數組;編譯時啓用所有警告並解決這些問題,等等)。

1

您在聲明中初始化了sPtr,您不需要這樣做,因爲您從不使用初始值。但是初始化會產生未定義的行爲,因爲它取決於command數組的內容,該數組在當時不確定。

作爲第二個參數傳遞給execvp()的數組預計在最後一個參數後面包含一個NULL指針。你不確定你的確如此。

此外,由於未將令牌分配給commandArgs[],您似乎將輸入命令的所有參數都刪除。標記後,您將複製第一個標記(僅),並將該副本分配給commandArgs的第一個元素,但其他任何標記都將被忽略。

+0

我在評論中指出了這一點。參數初始化存在問題。只有第一個參數可能被分配,最後一個參數後沒有NULL。 +1 –