gpt4 book ai didi

c - 用 C 写一个 shell,不返回任何东西

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

我运行我的 shell,它提示:“Shell>”。我键入一个命令,例如 ls,它只会生成一个新行,再次显示“Shell>”。

知道为什么它似乎没有命中 execv 吗?

            int no_of_args = count(buffer);
// plus one to make it NULL
char** array_of_strings = malloc((sizeof(char*)*(no_of_args+1)));

// break the string up and create an array of pointers that
// point to each of the arguments.
int count=0;
char* pch2;
pch2 = strtok (buffer," ");
while (pch2 != NULL)
{
array_of_strings[count]=(char*)malloc((sizeof(char)*strlen(pch2)));
strcpy(array_of_strings[count], pch2);

pch2 = strtok (NULL, " ");
count++;
}

//format for command is eg. ls -a -l
//therefore the first element in the array will be the program name
//add the path so it'll be /bin/command eg. /bin/ls
char* prog = malloc(sizeof(char)*(strlen(array_of_strings[0]+strlen(path))));
prog = strcat(strcpy(prog, path),array_of_strings[0]);


}

最佳答案

首先,您永远不需要使用sizeof(char),因为它始终为 1。

ISO C99 是这样定义字节的:

addressable unit of data storage large enough to hold any member of the basic character set of the execution environment.

以及 6.5.3.4 sizeof 运算符中的后续声明:

When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.

这在 C11 中没有变化。

所以,基本上,一个字节就是您的 char 的大小。 ISO 通常为 8 位值保留术语 octet


其次,语句序列如下:

array_of_strings[count]=(char*)malloc((sizeof(char)*strlen(pch2)));
strcpy(array_of_strings[count], pch2);

是未定义的行为,因为 strlen(pch2) 只是一个 short 足以存储 pch2 指向的字符串副本的空间>。你应该使用类似的东西:

array_of_strings[count] = malloc (strlen (pch2) + 1);

您还会注意到我删除了类型转换。永远不要强制转换 C 中内存分配函数的返回值,因为它在某些情况下会隐藏问题。

第三,您似乎没有遵守 argv 数组的规则。该数组中的最后一个元素应该是 NULL 指针,因为命令 ls x.txt 会生成:

  • “ls”
  • “x.txt”
  • NULL

现在,针对您的特定 问题。您应该检查 execv 调用的返回值,因为不能保证可执行文件会运行(例如,如果 ls 不在 /bin 目录)。我会改变:

int rv = execv(prog, array_of_strings);

进入:

printf ("DEBUG: [%s]\n", prog);
int rv = execv(prog, array_of_strings);
printf ("DEBUG: execv returned %d/%d\n", rv, errno); // need errno.h

用于调试目的,并查看输出的内容。

如果 execv 有效,您永远不会看到最后的消息。如果它出现,它会告诉您为什么 execv 不起作用。当我这样做时,我看到:

DEBUG: [/bin/ls
]
DEBUG: execv returned -1/2

换句话说,您尝试运行的可执行文件名称是 /bin/lsX,其中 X 是换行符。没有这样的可执行文件,因此来自 execv 的错误 2(ENOENT = 没有这样的文件或目录) - 您需要修复解析代码,以便不留下换行符中。

作为快速调试修复,我更改了行:

prog = strcat(strcpy(prog, path),array_of_strings[0]);

进入:

prog = strcat(strcpy(prog, path),array_of_strings[0]);
if (prog[strlen(prog)-1] == '\n') prog[strlen(prog)-1] = '\0';

去掉尾随的换行符,文件列表就成功了:

Shell>ls
DEBUG: [/bin/ls]
accounts2011.ods birthdays shares workspace_android
accounts2012.ods development wildlife
Shell>_

这只是为了证明而调试的东西,不适合真正的代码,所以你仍然需要去修复你的解析。


您可能想看看 this answer因为它显示了一种通过缓冲区溢出保护从用户那里获取输入的好方法,如果输入行太长则清理其余输入行,提示并(在这种情况下最重要)删除换行符。

关于c - 用 C 写一个 shell,不返回任何东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12523121/

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