2017-03-01 107 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 –