execvp 有问题
Having trouble with execvp
我在尝试用 c 编写的基本 shell 程序时遇到了一些问题。每当我尝试在 ls 等函数中调用 exec 时,execvp 都会 return 并出现错误,指出找不到文件或目录。我认为问题出在解析上,因为在 main 中,可以打印命令,但在函数中它是空白的。谢谢
函数代码如下:
int extern_process(char *arg[]){
pid_t pid;
int errnum, ifFail;
printf("i%si\n",arg[0]);
pid = fork();
if(pid == -1){
errnum = errno;
fprintf(stderr,"Error: fork %s", strerror(errnum));
return FAIL;
} else if(pid == 0){
ifFail = execvp(arg[0],arg);
if(ifFail < 0){
errnum = errno;
fprintf(stderr,"Error: exec %s", strerror(errnum));
return FAIL;
}
} else {
pid = wait(NULL);
}
return SUCCESS;
}
为了以防万一,下面是解析函数的代码:
void parse_cmd(char *retval[], char *cmd){
char *tmp;
char a[100];
strcpy(a,cmd);
int i = 0;
tmp = strtok(a," \n\t[=11=]");
if(retval == NULL){
fprintf(stderr, "Error with allocation\n");
return;
}
if(tmp == NULL){
printf("Error with parsing.\n");
return;
}
while(tmp != NULL){
retval[i] = tmp;
tmp = strtok(NULL," \n\t[=11=]");
i++;
}
retval[i] = NULL;
}
这是输出:
shell> ls
ls
i i
Error: exec no file or directory found
我很确定 strtok returns 是一个指向第一个参数的指针,在您的例子中,它是一个堆栈分配。我相信,返回指向该堆栈分配的指针数组会导致未定义的行为。这可能是也可能不是您问题的原因。不看更多代码就很难知道。要进行测试,请尝试像这样更改这部分代码:
void parse_cmd(char *retval[], char *cmd){
char *tmp;
char *a = strdup(cmd);
int i = 0;
在生产中使用它之前,您需要想出一些方法来确保释放 "a" 否则会发生泄漏。也许你可以 return 它而不是 void 并从其他地方释放它,或者你实际上可以 strdup() 每个标记并编写一个函数来释放它们全部或任何适合你的东西。
如果还有其他问题,可能在其他代码中。我真的看不出还有什么问题。
我在尝试用 c 编写的基本 shell 程序时遇到了一些问题。每当我尝试在 ls 等函数中调用 exec 时,execvp 都会 return 并出现错误,指出找不到文件或目录。我认为问题出在解析上,因为在 main 中,可以打印命令,但在函数中它是空白的。谢谢
函数代码如下:
int extern_process(char *arg[]){
pid_t pid;
int errnum, ifFail;
printf("i%si\n",arg[0]);
pid = fork();
if(pid == -1){
errnum = errno;
fprintf(stderr,"Error: fork %s", strerror(errnum));
return FAIL;
} else if(pid == 0){
ifFail = execvp(arg[0],arg);
if(ifFail < 0){
errnum = errno;
fprintf(stderr,"Error: exec %s", strerror(errnum));
return FAIL;
}
} else {
pid = wait(NULL);
}
return SUCCESS;
}
为了以防万一,下面是解析函数的代码:
void parse_cmd(char *retval[], char *cmd){
char *tmp;
char a[100];
strcpy(a,cmd);
int i = 0;
tmp = strtok(a," \n\t[=11=]");
if(retval == NULL){
fprintf(stderr, "Error with allocation\n");
return;
}
if(tmp == NULL){
printf("Error with parsing.\n");
return;
}
while(tmp != NULL){
retval[i] = tmp;
tmp = strtok(NULL," \n\t[=11=]");
i++;
}
retval[i] = NULL;
}
这是输出:
shell> ls
ls
i i
Error: exec no file or directory found
我很确定 strtok returns 是一个指向第一个参数的指针,在您的例子中,它是一个堆栈分配。我相信,返回指向该堆栈分配的指针数组会导致未定义的行为。这可能是也可能不是您问题的原因。不看更多代码就很难知道。要进行测试,请尝试像这样更改这部分代码:
void parse_cmd(char *retval[], char *cmd){
char *tmp;
char *a = strdup(cmd);
int i = 0;
在生产中使用它之前,您需要想出一些方法来确保释放 "a" 否则会发生泄漏。也许你可以 return 它而不是 void 并从其他地方释放它,或者你实际上可以 strdup() 每个标记并编写一个函数来释放它们全部或任何适合你的东西。
如果还有其他问题,可能在其他代码中。我真的看不出还有什么问题。