DragonOS/user/apps/shell/shell.c

216 lines
6.0 KiB
C
Raw Normal View History

#include <libc/unistd.h>
#include <libc/stdio.h>
#include <libc/fcntl.h>
2022-05-07 05:46:23 +00:00
#include <libc/stdlib.h>
2022-05-21 13:49:56 +00:00
#include <libKeyboard/keyboard.h>
2022-05-24 08:37:28 +00:00
#include <libc/string.h>
#include <libc/stddef.h>
2022-06-25 12:55:59 +00:00
#include <libc/sys/stat.h>
2022-05-24 08:37:28 +00:00
#include "cmd.h"
#define pause_cpu() asm volatile("pause\n\t");
2022-08-18 05:39:41 +00:00
#define MEM_HISTORY 1024
2022-05-24 08:37:28 +00:00
/**
* @brief
*
* @param fd
* @param buf
* @return
*/
2022-05-24 08:37:28 +00:00
int shell_readline(int fd, char *buf);
void print_ascii_logo();
2022-05-24 08:37:28 +00:00
extern char *shell_current_path;
//保存的历史命令(瞬时更改)
2022-08-18 05:39:41 +00:00
char history_commands[MEM_HISTORY][INPUT_BUFFER_SIZE];
//真正的历史命令
char real_history_commands[MEM_HISTORY][INPUT_BUFFER_SIZE];
2022-08-18 02:29:35 +00:00
int count_history;
//现在对应的命令
int current_command_index;
2022-05-24 08:37:28 +00:00
/**
* @brief shell主循环
*
* @param kb_fd
*/
2022-05-31 13:55:06 +00:00
void main_loop(int kb_fd)
{
2022-08-18 02:29:35 +00:00
count_history = 0;
current_command_index = 0;
2022-05-24 08:37:28 +00:00
unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0};
2022-05-07 05:46:23 +00:00
2022-05-24 08:37:28 +00:00
// 初始化当前工作目录的路径
2022-05-25 14:50:32 +00:00
shell_current_path = (char *)malloc(3);
2022-05-31 13:55:06 +00:00
2022-06-07 15:18:26 +00:00
memset(shell_current_path, 0, 3);
2022-05-25 14:50:32 +00:00
shell_current_path[0] = '/';
shell_current_path[1] = '\0';
2022-05-24 08:37:28 +00:00
// shell命令行的主循环
2022-05-21 13:49:56 +00:00
while (true)
{
2022-05-24 08:37:28 +00:00
int argc = 0;
char **argv;
2022-05-07 06:14:11 +00:00
2022-05-25 14:50:32 +00:00
printf("[DragonOS] %s # ", shell_current_path);
2022-05-31 13:55:06 +00:00
2022-05-24 08:37:28 +00:00
memset(input_buffer, 0, INPUT_BUFFER_SIZE);
2022-05-07 06:14:11 +00:00
2022-05-24 08:37:28 +00:00
// 循环读取每一行到buffer
count_history++;
2022-05-25 14:50:32 +00:00
int count = shell_readline(kb_fd, input_buffer);
if (!count || current_command_index < count_history - 1)
count_history--;
if (count)
{
strcpy(real_history_commands[count_history - 1], input_buffer);
count_history++;
memset(history_commands, 0, sizeof(history_commands));
for (int i = 0; i <= count_history - 2; i++)
strcpy(history_commands[i], real_history_commands[i]);
current_command_index = count_history - 1;
}
2022-05-25 14:50:32 +00:00
if (count)
{
2022-08-18 05:37:31 +00:00
char command_origin[strlen(input_buffer)];
2022-08-18 02:29:35 +00:00
strcpy(command_origin, input_buffer);
2022-05-25 14:50:32 +00:00
int cmd_num = parse_command(input_buffer, &argc, &argv);
printf("\n");
if (cmd_num >= 0)
shell_run_built_in_command(cmd_num, argc, argv);
}
else
printf("\n");
2022-05-24 08:37:28 +00:00
}
}
2022-05-07 06:14:11 +00:00
2022-05-24 08:37:28 +00:00
int main()
{
// 打开键盘文件
char kb_file_path[] = "/dev/keyboard.dev";
int kb_fd = open(kb_file_path, 0);
// printf("keyboard fd = %d\n", kb_fd);
print_ascii_logo();
// printf("before mkdir\n");
// mkdir("/aaac", 0);
// printf("after mkdir\n");
2022-05-24 08:37:28 +00:00
main_loop(kb_fd);
while (1)
;
}
2022-08-18 02:29:35 +00:00
/**
* @brief
*
* @param count
* @param buf
*/
void clear_command(int count, char *buf)
{
for (int i = 0; i < count; i++)
printf("%c", '\b');
memset(buf, 0, sizeof(buf));
}
/**
* @brief ()
*
* @param buf
* @param type 1,,-1,
*/
void change_command(char *buf, int type)
{
current_command_index -= type;
2022-08-18 02:29:35 +00:00
//处理边界
if (current_command_index < 0)
current_command_index++;
if (current_command_index >= count_history - 1)
current_command_index = count_history - 2;
strcpy(buf, history_commands[current_command_index]);
2022-08-18 02:29:35 +00:00
printf("%s", buf);
}
2022-05-24 08:37:28 +00:00
/**
* @brief
*
* @param fd
* @param buf
* @return
*/
int shell_readline(int fd, char *buf)
{
int key = 0;
int count = 0;
while (1)
2022-05-11 03:33:29 +00:00
{
2022-05-24 08:37:28 +00:00
key = keyboard_analyze_keycode(fd);
2022-08-18 02:29:35 +00:00
//向上方向键
if (count_history != 0 && key == 0xc8)
{
clear_command(count, buf);
count = 0;
//向历史
change_command(buf, 1);
count = strlen(buf);
}
//向下方向键
if (count_history != 0 && key == 0x50)
{
clear_command(count, buf);
count = 0;
//向现在
change_command(buf, -1);
count = strlen(buf);
}
2022-05-24 08:37:28 +00:00
if (key == '\n')
{
if (count > 0 && current_command_index >= count_history)
{
memset(history_commands[current_command_index - 1], 0, sizeof(history_commands[current_command_index - 1]));
count_history--;
}
2022-05-24 08:37:28 +00:00
return count;
}
2022-08-18 02:29:35 +00:00
if (key && key != 0x50 && key != 0xc8)
2022-05-11 03:33:29 +00:00
{
if (key == '\b')
{
if (count > 0)
{
buf[--count] = 0;
printf("%c", '\b');
}
}
else
{
buf[count++] = key;
printf("%c", key);
}
if (count > 0 && current_command_index >= count_history)
{
memset(history_commands[count_history], 0, sizeof(history_commands[count_history]));
strcpy(history_commands[count_history], buf);
}
else if (count > 0)
{
memset(history_commands[current_command_index], 0, sizeof(history_commands[current_command_index]));
strcpy(history_commands[current_command_index], buf);
}
2022-05-11 03:33:29 +00:00
}
2022-05-24 08:37:28 +00:00
// 输入缓冲区满了之后,直接返回
if (count >= INPUT_BUFFER_SIZE - 1)
return count;
pause_cpu();
2022-05-11 03:33:29 +00:00
}
2022-05-24 08:37:28 +00:00
}
void print_ascii_logo()
{
printf("\n\n");
printf(" ____ ___ ____ \n");
printf("| _ \\ _ __ __ _ __ _ ___ _ __ / _ \\ / ___| \n");
printf("| | | || '__| / _` | / _` | / _ \\ | '_ \\ | | | |\\___ \\ \n");
printf("| |_| || | | (_| || (_| || (_) || | | || |_| | ___) |\n");
printf("|____/ |_| \\__,_| \\__, | \\___/ |_| |_| \\___/ |____/ \n");
printf(" |___/ \n");
printf("\n\n");
}