gpt4 book ai didi

c - malloc on (char**)

转载 作者:太空宇宙 更新时间:2023-11-04 07:30:48 25 4
gpt4 key购买 nike

好吧,我正在尝试使用 C 为 linux 编写一个 shell。使用函数 fork() 和 execl(),我可以执行每个命令,但现在我无法读取参数:

char * command;
char ** c_args = NULL;

bytes_read = getline (&command, &nbytes, stdin);

command = strtok(command, "\n ");
int arg = 0;
c_arg = strtok(NULL, "\n ");
while( c_arg != NULL ) {
if( c_args == NULL ) {
c_args = (char**) malloc(sizeof(char*));
}
else {
c_args = (char**) realloc( c_args, sizeof(char*) * (arg + 1) );
}
c_args[arg] = (char*) malloc( sizeof(char)*1024 );
strcpy( c_args[arg], c_arg );
c_arg = strtok(NULL, "\n ");
arg++;
}
...
pid_t pid = fork()
...
...
execl( <path>, command, c_args, NULL)
...
...

这样,当我尝试传递参数时,我会从命令中得到错误,例如:

ls -l

给我:

ls: cannot access p��: No such file or directory

我知道问题出在 c_args 分配上。有什么问题吗?

干杯。

最佳答案

您不能将 execl() 用于可变参数列表;您需要使用 execv() 或其变体之一(execve()execvp() 等)。当您知道编译时将出现的所有参数时,您只能使用 execl()。在大多数情况下,通用 shell 不会知道这一点。一个异常(exception)是当你做类似的事情时:

execl("/bin/sh", "/bin/sh", "-c", command_line, (char *)0);

在这里,您将调用 shell 来运行单个字符串作为命令行(没有其他参数)。但是,当您在完整的 shell 中处理人们在键盘上键入的内容时,您将无法知道他们在编译时键入了多少参数。

在最简单的情况下,您应该使用:

execvp(c_args[0], c_args);

第零个参数,命令名称,应该是您传递给 execvp() 的内容。如果这是一个简单的文件名(没有 /),那么它将在 $PATH 环境变量的目录中查找命令。如果命令名包含斜杠,那么它会查找指定的(相对或绝对)文件名,如果存在则执行,如果不存在则失败。其他参数都应该在空终止列表 c_args 中。

现在,可能还有其他内存分配问题;我没有仔细检查代码。不过,您可以通过参数列表的诊断打印来检查它们:

char **pargs = c_args;
while (*pargs != 0)
puts(*pargs++);

在单独的行上打印每个参数。请注意,它直到遇到空指针才会停止;以 null 终止指向参数字符串的指针列表是至关重要的。

这段代码:

c_args[arg] = (char*) malloc( sizeof(char)*1024 );
strcpy( c_args[arg], c_arg );

在通常情况下看起来有点矫枉过正,在极端情况下内存分配不足。当你复制字符串时,分配足够的长度。我看到您正在使用 strtok() 来分解字符串 — 它适用于 shell 的早期版本,但是当您开始处理像 ls -l 这样的命令行时>$tmp,您会发现 strtok() 喜欢在您阅读分隔符之前踩踏它,这成为一种主要责任。但是,当您使用它时,您可能不必像那样复制参数;你可以设置 c_args[arg++] = result_from_strtok;。当你确实需要复制时,你应该使用 strdup();例如,它不会忘记为结尾的 '\0' 分配足够的空间,既不会过度分配也不会分配不足。

关于c - malloc on (char**),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13890222/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com