【发布时间】:2021-02-04 04:26:02
【问题描述】:
我正在尝试用 C 语言编写一个简单的 Shell。最终,我将实现进程和管道等的分叉。但是,现在,我只是想弄清楚所有的逻辑。
我有一个部分工作的 shell:当我键入 exit 时,它退出了......但是,我的令牌函数似乎无法正常工作。
我在这里做错了什么?我不确定它为什么会出现段错误。
Token 在while 循环中打印一次,然后出现段错误并崩溃。
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_BUF_SZ 1024
void checkForPipe(char *string, bool *pipe_bool);
void checkForRedirect(char *string, bool *redirect_bool);
void tokenizeInput(char *string, bool pipe, bool redirect);
int main()
{
char *ptr;
bool is_pipe = 0;
bool is_redirect_out = 0;
bool is_exit = 0;
ptr = (char*)malloc(MAX_BUF_SZ);
while(!is_exit)
{
// Diplay prompt
char cur_dir[MAX_BUF_SZ];
getcwd(cur_dir, MAX_BUF_SZ);
printf("SHELL:%s$ ", cur_dir);
fgets(ptr, MAX_BUF_SZ, stdin);
checkForPipe(ptr, &is_pipe);
checkForRedirect(ptr, &is_redirect_out);
printf("pipe flag = %d\n", is_pipe);
printf("redirect flag = %d\n", is_redirect_out);
if(strcmp(ptr, "exit\n") == 0)
{
is_exit = 1;
}
tokenizeInput(ptr, is_pipe, is_redirect_out);
}
return 0;
}
void checkForPipe(char *string, bool *pipe_bool)
{
char *check_for_pipes;
char *clean_compare;
check_for_pipes = (char*)malloc(MAX_BUF_SZ);
clean_compare = (char*)malloc(MAX_BUF_SZ);
strcpy(check_for_pipes, string);
strcpy(clean_compare, string);
char * token = strtok(check_for_pipes, "|");
if(strcmp(token, clean_compare) == 0)
{
free(clean_compare);
free(check_for_pipes);
}
else
{
*pipe_bool = 1;
free(clean_compare);
free(check_for_pipes);
}
}
void checkForRedirect(char *string, bool *redirect_bool)
{
char *check_for_redirects;
char *clean_compare;
check_for_redirects = (char*)malloc(MAX_BUF_SZ);
clean_compare = (char*)malloc(MAX_BUF_SZ);
strcpy(check_for_redirects, string);
strcpy(clean_compare, string);
char * token = strtok(check_for_redirects, ">");
if(strcmp(token, clean_compare) == 0)
{
free(clean_compare);
free(check_for_redirects);
}
else
{
*redirect_bool = 1;
free(clean_compare);
free(check_for_redirects);
}
}
void tokenizeInput(char *string, bool pipe, bool redirect)
{
char *copy_string;
copy_string = (char*)malloc(MAX_BUF_SZ);
strcpy(copy_string, string);
if(pipe == 0 && redirect == 0)
{
char **args = {NULL};
char *token = strtok(copy_string, " ");
int i = 0;
printf("%s\n", token);
while(token != NULL)
{
args[i] = token;
strtok(NULL, " ");
printf("%s\n", token);
i++;
}
}
/* printf("%s\n%s\n%s\n", args[0], args[1], args[2]); */
}
【问题讨论】:
-
使用调试器。至少您应该获得触发段错误的确切代码行并将其发布在您的问题中。您还可以使用调试器检查状态以查找可疑值和行为。
-
char **args = {NULL};这行不通。它不是一个适当大小的数组。您需要一个至少足够大的数组来存储所有令牌。 -
char **args是一个 指向指向char的指针的单个指针 -- 它只是一个指向包含更多指针的内存块或NULL的指针(不是它们的数组)。与任何指针一样,您必须确保它指向已分配给指针的有效内存。 (此时没有——这意味着它只是指向NULL的指针。)args[i]取消引用NULL指针,所以 BAM !段错误!