双指针作为execvp()的参数

时间:2019-01-12 15:32:25

标签: c shell execvp double-pointer

我尝试使用自定义execvp()双指针作为输入执行**tokens,而不是在“创建自定义外壳”分配上执行argv[],如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

int main(){
    char *token;
    char **tokens = malloc(sizeof(char*)*512); //512 is for the maximum input-command length
    char *command=malloc(sizeof(char)*512);
    int i = 0;
    pid_t child_pid;
    int status;
    //***********take input from user*************************************
    fgets(command,512,stdin);

    //***********parse input*********************************************
    token = strtok(command," \t");

    while( token != NULL ) {

        tokens[i]=token;
        i ++;
        token = strtok(NULL, " \t");

    }
    child_pid = fork();

    if(child_pid == 0) {
        /* This is done by the child process. */
        execvp(tokens[0], tokens);
    } else {
        waitpid(child_pid, &status, WUNTRACED);
    }
}

问题肯定在这条线上:

execvp(tokens[0], tokens);

,我只是不明白为什么无法执行并打印到我的 stdout。 我已经尝试过了:

execvp("ls", tokens);

,效果很好。 这:

printf("%s\n", tokens[0]);

输出为(根据测试输入:ls):

  

ls

2 个答案:

答案 0 :(得分:2)

您的代码中有几个问题,包括:

  1. 传递给execvp()的参数指针数组必须以空指针终止。您不确定。

  2. 如果缓冲区足够大,可以通过fgets获得的字符串将包含所有字符,直到该行的换行符为止。您不能在令牌定界符中包括换行符,因此对于单字命令ls,传递给execvp()的命令等效于"ls\n" not "ls"ls\n在您的计算机上不太可能(但并非不可能)。

  3. 您不会检查execvp()或任何其他函数的返回值,也不会处理任何错误。 execvp()的特殊之处在于它仅在出现错误时才返回,但是如果您通过发出错误消息来处理该情况,则可以避免一些混乱。

我纠正了其中的前两个问题之后,您的程序为我成功运行了一个“ ls”命令。

答案 1 :(得分:1)

您需要使用sizeof(char *)分配内存。

char **tokens = malloc(sizeof(char *)*512);
                                   ^^----------->Size of char pointer

到目前为止,您正在分配sizeof(char),从而调用未定义的行为。


还要考虑@ n.m指向的第一条评论