正在制作一个简单的shell,现在的小问题是,当我在空白行上按enter键时,程序失败(分段错误)。但是当我在delim字符串中取出'n'时,它可以正常工作,但随后命令执行不工作。
($)
Segmentation fault (core dumped)
而不是:
($)
($)
这是我的代码:
void get_cmd(char **userinput)
{
size_t r = 1000;
getline(userinput, &r, stdin);
}
char **split_str(char *buf)
{
char *token, **eachstr, *delim = " n";
int count = 0;
eachstr = malloc(sizeof(char) * 100);
if (!eachstr)
return (NULL);
token = strtok(buf, delim);
while (token)
{
eachstr[count] = token;
token = strtok(NULL, delim);
count++;
}
eachstr[count] = NULL;
return (eachstr);
}
int main(void)
{
unsigned int status = 1;
char *userinput, **args;
userinput = malloc(sizeof(char) * 1000);
if (!userinput)
{
perror("cant allocate memory");
exit(EXIT_FAILURE);
}
while (status)
{
_print("($) ");
get_cmd(&userinput);
args = split_str(userinput);
if (_strcmp(args[0], "exit") == 0)
status = 0;
execute(args);
free(args);
}
free(userinput);
return (0);
}
execute()函数链接:https://github.com/tcrz/simple_shell/blob/dev/exec.c
向getline()
撒谎的代码
getline()
需要一个指向指针的配对的指针和指向该缓冲区大小的指针。相反,它将指针和一个无关指针的地址传递给一个神奇的数字1000,但没有使它们保持同步。
代替main()
// char *userinput
// userinput = malloc(sizeof(char) * 1000);
size_t userinput_size = 1000; // add
char *userinput = malloc(userinput_size);
...
// get_cmd(&userinput);
getline(&userinput, &userinput_size, stdin);
无溢出保护,尺寸错误
char **eachstr;
// wrong size (sizeof a char??)
// eachstr = malloc(sizeof(char) * 100);
// right size (sizeof a char*)
eachstr = malloc(sizeof *eachptr * 100);
// while (token) {
while ((count + 1) < 100 && token) {
eachstr[count] = token;
浅拷贝
eachstr[count] = token;
只复制指针,token
不稳定。查看eachstr[count] = strdup(token);
以形成字符串的副本。(以后需要释放)
使用保护
_strcmp(args[0], "exit")
在args[0] == NULL
时为UB。@bruceg .
不清楚为什么代码不使用strcmp()
。
改进:魔术数字
避免malloc(sizeof(char) * 100);
中的神奇数字100。
与其猜测100就足够了,不如考虑strspn()/strcspn()
而不是strtok()
,并进行两次标记化,第一次确定所需的大小。
改进:执行"退出"?
当_strcmp(args[0], "exit") == 0
时,我不希望代码仍然调用execute()
。
可能还有其他问题。