5

我正在构建一个 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 和 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} 时)

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

4

2 回答 2

6

It think you passed whole command line in first argument to execvp

you have to separate first token(command name) from cmnd to pass as first argument of execvp

You can call it as

execvp(args[0], args);

于 2012-05-22T01:11:23.827 回答
1

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

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

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

于 2012-05-22T01:46:13.850 回答