mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 08:06:32 +00:00
🆕 cd命令
This commit is contained in:
@ -1,7 +1,10 @@
|
||||
all: shell.o cmd.o
|
||||
all: shell.o cmd.o cmd_help.o
|
||||
|
||||
shell.o: shell.c
|
||||
gcc $(CFLAGS) -c shell.c -o shell.o
|
||||
|
||||
cmd.o: cmd.c
|
||||
gcc $(CFLAGS) -c cmd.c -o cmd.o
|
||||
|
||||
cmd_help.o: cmd_help.c
|
||||
gcc $(CFLAGS) -c cmd_help.c -o cmd_help.o
|
||||
|
@ -3,6 +3,12 @@
|
||||
#include <libc/stdio.h>
|
||||
#include <libc/stddef.h>
|
||||
#include <libsystem/syscall.h>
|
||||
#include <libc/string.h>
|
||||
#include <libc/errno.h>
|
||||
#include <libc/unistd.h>
|
||||
#include <libc/stdlib.h>
|
||||
|
||||
#include "cmd_help.h"
|
||||
|
||||
// 当前工作目录(在main_loop中初始化)
|
||||
char *shell_current_path = NULL;
|
||||
@ -22,6 +28,7 @@ struct built_in_cmd_t shell_cmds[] =
|
||||
{"rmdir", shell_cmd_rmdir},
|
||||
{"reboot", shell_cmd_reboot},
|
||||
{"touch", shell_cmd_touch},
|
||||
{"help", shell_help},
|
||||
|
||||
};
|
||||
// 总共的内建命令数量
|
||||
@ -69,8 +76,112 @@ void shell_run_built_in_command(int index, int argc, char **argv)
|
||||
* @param argv
|
||||
* @return int
|
||||
*/
|
||||
// todo:
|
||||
int shell_cmd_cd(int argc, char **argv) {}
|
||||
|
||||
int shell_cmd_cd(int argc, char **argv)
|
||||
{
|
||||
|
||||
int current_dir_len = strlen(shell_current_path);
|
||||
if (argc < 2)
|
||||
{
|
||||
shell_help_cd();
|
||||
goto done;
|
||||
}
|
||||
// 进入当前文件夹
|
||||
if (!strcmp(".", argv[1]))
|
||||
goto done;
|
||||
|
||||
// 进入父目录
|
||||
if (!strcmp("..", argv[1]))
|
||||
{
|
||||
|
||||
// 当前已经是根目录
|
||||
if (!strcmp("/", shell_current_path))
|
||||
goto done;
|
||||
|
||||
// 返回到父目录
|
||||
int index = current_dir_len - 1;
|
||||
for (; index > 1; --index)
|
||||
{
|
||||
if (shell_current_path[index] == '/')
|
||||
break;
|
||||
}
|
||||
shell_current_path[index] = '\0';
|
||||
|
||||
// printf("switch to \" %s \"\n", shell_current_path);
|
||||
goto done;
|
||||
}
|
||||
|
||||
int dest_len = strlen(argv[1]);
|
||||
// 路径过长
|
||||
if (dest_len >= SHELL_CWD_MAX_SIZE - 1)
|
||||
{
|
||||
printf("ERROR: Path too long!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (argv[1][0] == '/')
|
||||
{
|
||||
// ======进入绝对路径=====
|
||||
int ec = chdir(argv[1]);
|
||||
if (ec == -1)
|
||||
ec = errno;
|
||||
if (ec == 0)
|
||||
{
|
||||
// 获取新的路径字符串
|
||||
char *new_path = (char *)malloc(dest_len + 2);
|
||||
memset(new_path, 0, dest_len + 2);
|
||||
strncpy(new_path, argv[1], dest_len);
|
||||
|
||||
// 释放原有的路径字符串的内存空间
|
||||
free(shell_current_path);
|
||||
|
||||
shell_current_path = new_path;
|
||||
|
||||
shell_current_path[dest_len] = '\0';
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
goto fail;; // 出错则直接忽略
|
||||
}
|
||||
else
|
||||
{
|
||||
int new_len = current_dir_len + dest_len;
|
||||
// ======进入相对路径=====
|
||||
if (new_len >= SHELL_CWD_MAX_SIZE - 1)
|
||||
{
|
||||
printf("ERROR: Path too long!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// 拼接出新的字符串
|
||||
char *new_path = (char *)malloc(new_len + 2);
|
||||
memset(new_path, 0, sizeof(new_path));
|
||||
strncpy(new_path, shell_current_path, current_dir_len);
|
||||
|
||||
if (current_dir_len > 1)
|
||||
new_path[current_dir_len] = '/';
|
||||
strcat(new_path, argv[1]);
|
||||
|
||||
if (chdir(new_path) == 0) // 成功切换目录
|
||||
{
|
||||
free(shell_current_path);
|
||||
new_path[new_len] = '\0';
|
||||
shell_current_path = new_path;
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ERROR: Cannot switch to directory: %s\n", new_path);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
fail:;
|
||||
done:;
|
||||
// 释放参数所占的内存
|
||||
free(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 查看文件夹下的文件列表
|
||||
@ -80,7 +191,10 @@ int shell_cmd_cd(int argc, char **argv) {}
|
||||
* @return int
|
||||
*/
|
||||
// todo:
|
||||
int shell_cmd_ls(int argc, char **argv) {}
|
||||
int shell_cmd_ls(int argc, char **argv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 显示当前工作目录的命令
|
||||
@ -93,6 +207,8 @@ int shell_cmd_pwd(int argc, char **argv)
|
||||
{
|
||||
if (shell_current_path)
|
||||
printf("%s\n", shell_current_path);
|
||||
|
||||
free(argv);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// cwd字符串的最大大小
|
||||
#define SHELL_CWD_MAX_SIZE 256
|
||||
|
||||
/**
|
||||
* @brief shell内建命令结构体
|
||||
*
|
||||
|
23
user/apps/shell/cmd_help.c
Normal file
23
user/apps/shell/cmd_help.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "cmd_help.h"
|
||||
#include <libc/stdio.h>
|
||||
struct help_table_item_t
|
||||
{
|
||||
void (*func)();
|
||||
};
|
||||
struct help_table_item_t help_table[] = {
|
||||
{shell_help_cd},
|
||||
};
|
||||
|
||||
static const int help_table_num = sizeof(help_table) / sizeof(struct help_table_item_t);
|
||||
|
||||
void shell_help()
|
||||
{
|
||||
printf("Help:\n");
|
||||
for (int i = 0; i < help_table_num; ++i)
|
||||
help_table[i].func();
|
||||
}
|
||||
|
||||
void shell_help_cd()
|
||||
{
|
||||
printf("Example of cd: cd [destination]\n");
|
||||
}
|
10
user/apps/shell/cmd_help.h
Normal file
10
user/apps/shell/cmd_help.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "cmd.h"
|
||||
void shell_help();
|
||||
|
||||
/**
|
||||
* @brief cd命令的帮助信息
|
||||
*
|
||||
*/
|
||||
void shell_help_cd();
|
@ -42,9 +42,10 @@ static void main_loop(int kb_fd)
|
||||
unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0};
|
||||
|
||||
// 初始化当前工作目录的路径
|
||||
shell_current_path = (char *)malloc(256);
|
||||
memset(shell_current_path, 0, 256);
|
||||
shell_current_path = "/";
|
||||
shell_current_path = (char *)malloc(3);
|
||||
memset(shell_current_path, 0, 3);
|
||||
shell_current_path[0] = '/';
|
||||
shell_current_path[1] = '\0';
|
||||
|
||||
// shell命令行的主循环
|
||||
while (true)
|
||||
@ -52,17 +53,22 @@ static void main_loop(int kb_fd)
|
||||
int argc = 0;
|
||||
char **argv;
|
||||
|
||||
printf("[DragonOS] # ");
|
||||
printf("[DragonOS] %s # ", shell_current_path);
|
||||
memset(input_buffer, 0, INPUT_BUFFER_SIZE);
|
||||
|
||||
// 循环读取每一行到buffer
|
||||
shell_readline(kb_fd, input_buffer);
|
||||
int count = shell_readline(kb_fd, input_buffer);
|
||||
|
||||
int cmd_num = parse_command(input_buffer, &argc, &argv);
|
||||
printf("\n");
|
||||
if (cmd_num >= 0)
|
||||
shell_run_built_in_command(cmd_num, argc, argv);
|
||||
|
||||
if (count)
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,13 +126,14 @@ int shell_readline(int fd, char *buf)
|
||||
*/
|
||||
int parse_command(char *buf, int *argc, char ***argv)
|
||||
{
|
||||
// printf("parse command\n");
|
||||
int index = 0; // 当前访问的是buf的第几位
|
||||
// 去除命令前导的空格
|
||||
while (index < INPUT_BUFFER_SIZE && buf[index] == ' ')
|
||||
++index;
|
||||
|
||||
// 计算参数数量
|
||||
for (int i = index; i < INPUT_BUFFER_SIZE - 1; ++i)
|
||||
for (int i = index; i < (INPUT_BUFFER_SIZE - 1); ++i)
|
||||
{
|
||||
// 到达了字符串末尾
|
||||
if (!buf[i])
|
||||
@ -140,13 +147,12 @@ int parse_command(char *buf, int *argc, char ***argv)
|
||||
// 为指向每个指令的指针分配空间
|
||||
*argv = (char **)malloc(sizeof(char **) * (*argc));
|
||||
memset(*argv, 0, sizeof(char **) * (*argc));
|
||||
|
||||
// 将每个命令都单独提取出来
|
||||
for (int i = 0; i < *argc && index < INPUT_BUFFER_SIZE; ++i)
|
||||
{
|
||||
// 提取出命令,以空格作为分割
|
||||
*((*argv) + i) = &buf[index];
|
||||
while (index < INPUT_BUFFER_SIZE - 1 && buf[index] && buf[index] != ' ')
|
||||
while (index < (INPUT_BUFFER_SIZE - 1) && buf[index] && buf[index] != ' ')
|
||||
++index;
|
||||
buf[index++] = '\0';
|
||||
|
||||
|
Reference in New Issue
Block a user