【问题标题】:execvp failing with multiple or no argumentsexecvp 失败,有多个参数或没有参数
【发布时间】:2013-12-26 00:27:30
【问题描述】:

我正在使用 C 语言开发一个非常基本的 UNIX shell。在这个项目中,我尝试使用 fork()execvp() 来执行实际的 shell 命令。我遇到了一个问题,它似乎可以与具有单个参数的命令一起正常工作(例如 ls -lecho howareyoutoday 工作完美),但具有多个参数的命令无法执行(echo how are you today 不跑步)。我将引导您了解我的代码/基本原理,以帮助您找出此问题背后的原因。

                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);
                            }
                    }
    }
}

【问题讨论】:

    标签: c shell arguments exec execvp


    【解决方案1】:

    您需要将您的参数字符串以空值终止到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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多