2013-12-09 103 views
2

我正在C中使用一个非常基本的UNIX shell。在此项目中,我试图使用fork()execvp()来执行实际的shell命令。尽管我遇到了一个问题,它似乎对具有单个参数的命令(例如ls -lecho howareyoutoday完美工作)的命令正常工作,但具有多个参数的命令无法执行(echo how are you today不运行)。我会通过我的代码/理由来帮助您找出造成这个问题的原因。execvp失败,具有多个参数或没有参数

   char *token; 
       int count=0; 
       pid_t childProc; 
       int childStatus; 
       pid_t tpid; 
       char* argv[256]; 
       int i=1; 

         childProc = fork(); 

          if (childProc==0) { 
            //CHILD PROCESS IS HERE 
            argv[0] = malloc(strlen(token)); 
            argv[0] = token; 

            token=strtok(NULL," \n\t()<>|&;"); 
            while(token!=NULL) { 
              argv[i]=malloc(strlen(token)); 
              argv[i]=token; 
              token=strtok(NULL," \n\t()<>|&;"); 
              i++; 
            } 
            execvp(argv[0],argv); 

            //if this executes execvp fails 
            printf("failure to execute\n"); 
            i=0; 
            exit(0); 
          } 
          else { 
            //PARENT PROCESS IS HERE 
            do { 
              tpid = wait(&childStatus); 
            } while(tpid != childProc); 
          } 

因此,它开始与调用基本的fork()创建子进程。在该子进程中,我为我的argv数组中的第一个元素分配内存。来自以前的strtok呼叫的token分配给argv[0]。生成新的token并添加到下一个argv元素。对剩余的令牌重复该过程。

一旦argv数组完成,execvp被调用,第一个参数包含命令名称,第二个参数是整个argv数组。如果命令执行失败,则execvp将返回并显示一条消息,指示将会打印此消息。

我不明白为什么我有上面提到的多个参数问题。任何帮助或建议将不胜感激!

仅供参考,完整程序的代码如下:

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    char buffer[256]; 
    char *token; 
    int count=0; 
    pid_t childProc; 
    int childStatus; 
    pid_t tpid; 
    char* argv[256]; 
    int i=1; 
    int j=0; 

    while(1) { 
      fgets(buffer, 256, stdin); 

      token=strtok(buffer," \n\t()<>|&;"); 

      while (token==NULL) { 
        fgets(buffer,256,stdin); 
        token=strtok(buffer," \n\t()<>|&;"); 
      } 

        if (strcmp(token,"exit")==0) { 
          exit(0); 
        } 
        else if (strcmp(token,"cd")==0) { 
          token = strtok(NULL, " \n\t()<>|&;"); 

          if (chdir(token)!=0) { 
            perror("Error: "); 
          } 
        } 
        else { 
          childProc = fork(); 

          if (childProc==0) { 
            argv[0] = malloc(strlen(token)); 
            argv[0] = token; 

            token=strtok(NULL," \n\t()<>|&;"); 
            while(token!=NULL) { 
              argv[i]=malloc(strlen(token)); 
              argv[i]=token; 
              token=strtok(NULL," \n\t()<>|&;"); 
              i++; 
            } 
            execvp(argv[0],argv); 

            //if this executes execvp fails 
            printf("failure to execute\n"); 
            i=0; 
            exit(0); 
          } 
          else { 
            do { 
              tpid = wait(&childStatus); 
            } while(tpid != childProc); 
          } 
        } 
    } 
} 

回答

0

您需要空终止你的论点串execvp

if (childProc == 0) 
{ 
    argv[0] = malloc(strlen(token)); 
    argv[0] = token; 

    token = strtok(NULL, " \n\t()<>|&;"); 

    while (token != NULL) 
    { 
     argv[i] = malloc(strlen(token)); 
     argv[i] = token; 
     token = strtok(NULL, " \n\t()<>|&;"); 
     i++; 
    } 

    argv[i] = NULL; //<--- insert here 

    if (execvp(argv[0], argv) == -1) 
    { 
     printf("failure to execute because %s\n", strerror(errno)); 
     exit(0); 
    } 
}