构建一个 C 外壳。execvp 返回'No such file'错误。使用 Malloc 即时创建 Argv 阵列



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

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

mysh some/path $ ps -a 

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

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

因此,我在我的进程中调用fork和execvp(cmnd,args(,其中cmnd是"ps",args如上所述,以及错误等。

我得到

'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 和 Erealloc 只是内置错误检查的 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} 时

(

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

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

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

您可以将其称为

execvp(args[0], args);

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

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

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

最新更新