双指针作为 execvp() 的参数
Double pointer as argument to execvp()
我正在尝试使用自定义 **tokens
双指针作为输入来执行 execvp()
,而不是 "create a custom shell" 赋值上的 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
您需要使用sizeof(char *)
分配内存。
char **tokens = malloc(sizeof(char *)*512);
^^----------->Size of char pointer
截至目前,您正在分配 sizeof(char)
从而调用未定义的行为。
还要考虑@n.m
指出的第一条评论
您的代码有几个问题,包括:
传递给 execvp()
的参数指针数组必须以空指针结尾。你不保证。
通过fgets
获得的字符串将包括所有字符直至并包括该行的换行符,如果缓冲区足够大以容纳它的话。您不在令牌定界字符中包含换行符,因此对于单字命令 ls
,传递给 execvp()
的命令等同于 "ls\n"
, 而不是 "ls"
。 ls\n
不太可能(但并非不可能)是您计算机上可用的命令。
您不检查 execvp()
或任何其他函数的 return 值,也不处理任何错误。 execvp()
的特殊之处在于它 return 仅在出现错误时才会出现,但如果您通过发出错误消息来处理这种情况,就可以避免一些混乱。
在我更正了其中的前两个之后,您的程序成功地为我运行了一个 "ls" 命令。
我正在尝试使用自定义 **tokens
双指针作为输入来执行 execvp()
,而不是 "create a custom shell" 赋值上的 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
您需要使用sizeof(char *)
分配内存。
char **tokens = malloc(sizeof(char *)*512);
^^----------->Size of char pointer
截至目前,您正在分配 sizeof(char)
从而调用未定义的行为。
还要考虑@n.m
指出的第一条评论您的代码有几个问题,包括:
传递给
execvp()
的参数指针数组必须以空指针结尾。你不保证。通过
fgets
获得的字符串将包括所有字符直至并包括该行的换行符,如果缓冲区足够大以容纳它的话。您不在令牌定界字符中包含换行符,因此对于单字命令ls
,传递给execvp()
的命令等同于"ls\n"
, 而不是"ls"
。ls\n
不太可能(但并非不可能)是您计算机上可用的命令。您不检查
execvp()
或任何其他函数的 return 值,也不处理任何错误。execvp()
的特殊之处在于它 return 仅在出现错误时才会出现,但如果您通过发出错误消息来处理这种情况,就可以避免一些混乱。
在我更正了其中的前两个之后,您的程序成功地为我运行了一个 "ls" 命令。