gpt4 book ai didi

c - 这个 shell 是做什么的?

转载 作者:行者123 更新时间:2023-11-30 17:38:47 29 4
gpt4 key购买 nike

我收到了这段代码作为如何制作“迷你 shell ”的示例,但我不知道它在做什么——我理解主函数中的大部分内容,但它上面的函数初始化我真的很失落。

任何有关 shell 如何工作的基础知识以及 C 中的一些较低级别函数将不胜感激。

log_t Log;

void printLog(log_t *l){
log_entry_t *tmp = l->tail;
while(tmp != NULL){
printf("%s\n", tmp->value);
tmp = tmp->prev;
}
}

int countArg(char *line){
unsigned int i, count = 0;
for(i = 0; i < strlen(line); i++){
if(line[i] == ' ')
count++;
}
return count + 1;
}

char **makeargv(char *line){
char *buff;
char **retv;
unsigned int i, count, arg_num = 0;

buff = malloc((strlen(line) + 1) * sizeof(char));
strcpy(buff, line);

arg_num = countArg(buff);

retv = malloc((arg_num + 1) * sizeof(char*));

retv[arg_num] = NULL;
retv[0] = buff;

for(i = 0, count = 1; buff[i]!='\0'; i++){
if(buff[i] == ' '){
buff[i]='\0';
retv[count] = buff + i + 1;
count++;
}
}
return retv;
}


int main()
{
log_init(&Log);
char * line;

while(1){
size_t size;
char * cwd = NULL;
char * query = NULL;
char * match = NULL;

int f_exit = 0,
f_nbi=0,
f_match=0,
f_sys = 0,
f_path=0;

// print out the requested prompt
cwd = getcwd(NULL,0);
printf("$(pid=%d)%s$ ", getpid(), cwd );
free(cwd);

line = NULL;
fflush(stdout);
getline(&line, &size, stdin);
line[strlen(line)-1] = '\0';

while(1){
if(strcmp(line, "exit") == 0){
if(f_match) printf("%s matches %s\n", query, line);
f_exit = 1;
printf("Command executed by pid=%d\n",getpid());
log_destroy(&Log);
break;
}
else if(strncmp(line, "cd ", 3) == 0){
if(f_match) printf("%s matches %s\n", query, line);
printf("Command executed by pid=%d\n",getpid());
log_push(&Log, line);
if(chdir(line + 3) != 0){
printf("%s: No such file or directory\n",(line + 3));
}
break;
}
else if(strcmp(line, "!#") == 0){
if(f_match) printf("%s matches %s\n", query, line);
printf("Command executed by pid=%d\n",getpid());
printLog(&Log);
break;
}
else if(strstr(line,"!")==line){
if(f_match) printf("%s matches %s\n", query, line);
query = line+1;
match = log_search(&Log, query);

if(match==NULL){
printf("Command executed by pid=%d\n",getpid());
printf("No Match\n");
break;
}
else{
f_match = 1;
printf("Command executed by pid=%d\n",getpid());
line = malloc((strlen(match)+1)*sizeof(char));
strcpy(line, match);
continue;
}
}
else{
f_nbi = 1;
log_push(&Log,line);
if(strstr(line,"/"))
f_path = 1;
break;
}
}

if(f_exit)
break;

if(f_nbi){
pid_t pid = fork();
if(pid == 0){ //child
if(f_match){
printf("%s matches %s\n", query, line);
free(query-1);
}

printf("Command executed by pid=%d\n",getpid());
char **argv = makeargv(line);
f_sys = 0;

if(f_path)
f_sys = execv(argv[0],&argv[0]);
else
f_sys = execvp(argv[0],&argv[0]);

if(f_sys == -1)
printf("%s: not found\n",line);

free(argv[0]);
free(argv);
log_destroy(&Log);
exit(0);

}
else { //parent
waitpid(pid, NULL, WUNTRACED);
if(f_match)
free(query-1);
}
}
free(line);
line = NULL;
}
if(line != NULL){
free(line);
line = NULL;
}

return 0;
}

最佳答案

printLog()函数只是打印结构类型中给定名称 log_t 的记录链接列表中的所有数据。通过typedef 。它从列表的尾部开始并向后工作。目前尚不清楚该列表是单链表还是双链表,但prev通常只出现在双链表中。

countArgs()函数是确定命令行上存在多少个参数的粗略方法。它很粗糙,因为它没有考虑引号或多个相邻空格。然而,这些仅仅意味着它高估了参数的数量,这并不严重。它不将制表符识别为分隔符,这对于 shell 来说是不寻常的。

makeargv()函数将命令行分割成一系列空格分隔的单词,并将单词列表返回给调用函数。它有效地解析命令行,确保命令行末尾有一个空指针。同样,它很简单,但足够了。与其他两个函数相比,它的命名也不一致。

关于c - 这个 shell 是做什么的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22032928/

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