我正在尝试用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 = %dn", is_pipe);
printf("redirect flag = %dn", is_redirect_out);
if(strcmp(ptr, "exitn") == 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("%sn", token);
while(token != NULL)
{
args[i] = token;
strtok(NULL, " ");
printf("%sn", token);
i++;
}
}
/* printf("%sn%sn%sn", args[0], args[1], args[2]); */
}
问题出在args[i]
上我将你的代码修改如下:
假设你有一个预先知道的令牌数,它是MAX_BUF_SZ
。分配类型为char*
的MAX_BUF_SZ指针
char **args = malloc(MAX_BUF_SZ * sizeof(char *));
,在循环中,你仍然需要在使用它之前分配每个指针char*
:
while(token != NULL)
{
args[i] = (char *)malloc(strlen(token)+1);
printf("%sn", token);
args[i] = token;
token = strtok(NULL, " ");
i++;
}
整个函数如下:
void tokenizeInput(char *string, bool pipe, bool redirect)
{
char *copy_string;
copy_string = (char*)malloc(MAX_BUF_SZ);
strcpy(copy_string, string);
// suppose we would have MAX_BUF_SZ tokens
char **args = malloc(MAX_BUF_SZ * sizeof(char *));
if(pipe == 0 && redirect == 0)
{
char *token = strtok(copy_string, " ");
int i = 0;
//printf("token %sn", token);
while(token != NULL)
{
args[i] = (char *)malloc(strlen(token)+1);
printf("%sn", token);
args[i] = token;
token = strtok(NULL, " ");
i++;
}
}
/* printf("%sn%sn%sn", args[0], args[1], args[2]); */
}
下面是我的例子:
SHELL:D:UsersT0180694DocumentsMes Outils PersonnelsPANPAN_folder$ test is essai of you and me
pipe flag = 0
redirect flag = 0
test
is
essai
of
you
and
me