【问题标题】:Building a C shell. execvp returns 'No such file' error. creating argv array on-the-fly with malloc构建一个 C shell。 execvp 返回“没有这样的文件”错误。使用 malloc 即时创建 argv 数组
【发布时间】:2012-05-28 11:37:02
【问题描述】:

我正在构建一个 shell,但系统调用“execvp”遇到了一些问题。我看到了有关此主题的其他一些问题,但它们含糊不清,似乎没有得到完全解决(提出问题的人都没有提供太多信息,也没有得到好的答案)。

显然我有自己的命令行,我正在从标准输入读取用户输入,例如

mysh some/path $ ps -a 

我正在构建一个 args 数组作为 char ** 并且数组本身可以工作(我认为),因为当我打印出函数中的值时,它会显示

args[0] = 'ps'
args[1] = '-a'
args[2] = '(null)'

所以,我在我的进程中调用 fork 和 execvp(cmnd, args),其中 cmnd 是“ps”,args 如上所述,以及 perror 等。

我明白了

'Error: no such file or directory.'  

我需要放入 $PATH 变量吗?我是不是在做其他奇怪的事情?

这是我生成 args 数组的代码:

char ** get_args(char * cmnd) {
int index = 0;
char **args = (char **)emalloc(sizeof(char *));
char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd)));
strncpy(copy,cmnd,strlen(cmnd));
char * tok = strtok(copy," ");
while(tok != NULL) {
    args[index] = (char *) emalloc(sizeof(char)*(strlen(tok)+1));
    strncpy(args[index],tok,strlen(tok)+1);
    index++;
    tok = strtok(NULL," ");
    args = (char**) erealloc(args,sizeof(char*)*(index+1));
}
args[index] = NULL;
return args;
}

(emalloc 和 eralloc 只是 malloc 和 realloc 内置错误检查)

那么我这样做:

void exec_cmnd(char*cmnd, char**args) {
pid_t pid;
if((pid=fork())==0) {
    execvp(cmnd, args);
    perror("Error");
    free(args);
    free(cmnd);
    exit(1);
}
else {
    int ReturnCode;
    while(pid!=wait(&ReturnCode)) {
        ;
    }
}
}

就像我上面说的,当在我的进程中调用 execvp 时,当我提供任何参数但没有它们时它会失败(即当 argv == {'ps', NULL} 时)

如果您需要更多信息,请随时询问。我需要解决这个问题。

【问题讨论】:

    标签: c shell malloc process execvp


    【解决方案1】:

    它认为你在第一个参数中将整个命令行传递给execvp

    您必须将第一个令牌(命令名称)与cmnd 分开才能作为execvp 的第一个参数传递

    你可以称之为

    execvp(args[0], args);

    【讨论】:

    • 这完全正确。如果要执行ps -a,需要调用execvp("ps", {"ps", "-a", NULL})
    【解决方案2】:

    请注意,由于以下原因,您有一个未终止的字符串:

    char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd)));
    strncpy(copy, cmnd, strlen(cmnd));
    

    strncpy() 在您这样使用它时不会为您终止。您还需要为空值再分配一个字节。如果您可以使用strdup(),请考虑使用它。如果没有,请考虑编写它。即使使用emalloc()erealloc() 的错误检查版本,这种错误分配也是一个问题。

    【讨论】:

    • 或者为了配合主题,使用(或实现并使用)estrdup()
    • char * estrdup(char * str) { int len = (int)(strlen(str)+1); char * copy = (char * ) emalloc(sizeof(char)*len); strncpy(copy,str,len); if(copy==NULL) { printf("Error duplicating '%s'\n",str); exit(1); } return copy; }
    • 好(几乎):将其更改为 size_t len 并丢失转换,因为 malloc()strncpy() 的参数也是 size_t。请注意,您应该复制到它之前检查copy,而不是之后!并且参数应该是char const *str,因为你不打算修改它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2017-12-15
    • 1970-01-01
    相关资源
    最近更新 更多