2014-02-24 61 views
0
#include<stdio.h> 
#include<unistd.h> 
#include<sys/types.h> 
#include<stdlib.h> 
#include<string.h> 
#define MAX_LINE 80 /* Maximum length of command*/ 
struct node 
{ 
char commandName[41]; 
struct node *next; 
}*start=NULL; 


void insert_at_beg(char cmd[]) 
{ 
struct node *new_node,*current; 

new_node=(struct node *)malloc(sizeof(struct node)); 

if(new_node == NULL) 
printf("nFailed to Allocate Memory"); 

strcpy(new_node->commandName, cmd); 
new_node->next=NULL; 

if(start==NULL) 
{ 
    start=new_node; 
    current=new_node; 
} 
else 
{ 
    new_node->next=start; 
    start=new_node; 
} 
} 
void display() 
{ 
struct node *temp; 
temp=start; 
while(temp!=NULL) 
{ 
    printf("\t%s\n",temp->commandName); 
    temp=temp->next; 
} 
} 

上面的代碼是一個鏈接列表,它使用結構來實現我自己的shell中的歷史記錄功能。 insert_at_beg()用於將我們在shell中輸入的命令作爲節點添加到列表中,並使用display()來顯示列表。execvp()不在我自己的shell中執行任何命令

以下是主要功能。在此功能中,我創建了自己的外殼

int main() 
{ 
char *args[MAX_LINE/2+1]; /* Command Line Argument*/ 
int should_run=1, status, i, num, error; 
pid_t pid; 
char str[41]; 
char teststr[10]={"history\0"}; 
char temprory[41]; 
const char delimiter[2]=" "; 
char *token; 

while(should_run) 
{ 
i=0; 
printf("osh>"); 
fflush(stdout); 

fgets(str, sizeof str, stdin); 
str[strlen(str)-1]='\0'; 
strncpy(temprory, str, sizeof(temprory)); 

token=strtok(str, " "); 

    while(token) 
    { 
     args[i]=strdup(token); 

     i++; 
     token=strtok(NULL, " "); 
    } 

    insert_at_beg(args[0]); 

    if((strcmp(args[0],teststr))==0) 
    { 
     display(); 
    } 
    else 
    { 
     ; 
    } 

    pid=fork(); 
    if(pid<0) // error in creating child process 
    { 
     printf("\tError in creating child process\n"); 
    }  
    else if(pid==0) //child process will execute this block 
    { 

     error=execvp(args[0], args); //execvp() always return -1 for any 
     if(error==-1)    //command I type in i.e. that command 
     {       //is not found and hence not executed. 
      printf("bash:command not found\n"); 
     } 
       exit(1); 
    } 
    else  //parent process will execute this block 
    { 
     pid=wait(&status); 

    if(!strcmp(args[0], "exit")) 
    { 
      should_run=0; 
    } 
    } 
    } 
    return 0; 
} 

如何繼續解決此問題並使其工作?我長期以來一直陷於這種情況。在這裏需要幫助。

+0

雖然'execvp'返回'-1',那麼'errno'中設置的值是什麼? – starrify

+0

errno 14即將到達所有命令 – Malhar

+0

另外,'execvp'的第二個參數應該是一個指針數組,它應該以NULL結構指針結束。我沒看見你用你的'args'來維護它。 – starrify

回答

0

man 3 execvp引用:

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

雖然您沒有用空指針終止args的數組。

添加此行:

args[i] = NULL; 

你的循環之後:

while(token) 
{ 
    args[i]=strdup(token); 
    i++; 
    token=strtok(NULL, " "); 
} 

解決您的問題。 (至少在我的筆記本電腦上,問題解決了。)

+0

但是,如果我們必須用NULL指針終止args數組,我們不能使用args [i + 1]而不是args [i]? – Malhar

+0

btw我嘗試使用args [i + 1]而不是args [i],但它不起作用。 – Malhar

+0

@ user1478588我不認爲用'args [i + 1]'替換'args [i]'應該可以。你所做的就是將第一個元素保留在未初始化的'args'中,而沒有做任何特殊的事情來終止這個數組。 – starrify