Browse Source

:new: cd命令

fslongjin 2 years ago
parent
commit
37669ebf87

+ 67 - 3
kernel/syscall/syscall.c

@@ -140,7 +140,7 @@ uint64_t sys_open(struct pt_regs *regs)
         printk_color(ORANGE, BLACK, "Can`t find file\n");
 
     kfree(path);
-    if (dentry == NULL) 
+    if (dentry == NULL)
         return -ENOENT;
 
     // 暂时认为目标是目录是一种错误
@@ -445,7 +445,7 @@ uint64_t sys_sbrk(struct pt_regs *regs)
 /**
  * @brief 重启计算机
  *
- * @return 
+ * @return
  */
 uint64_t sys_reboot(struct pt_regs *regs)
 {
@@ -455,6 +455,69 @@ uint64_t sys_reboot(struct pt_regs *regs)
     return 0;
 }
 
+/**
+ * @brief 切换工作目录
+ *
+ * @param dest_path 目标路径
+ * @return
++--------------+------------------------+
+|    返回码    |          描述          |
++--------------+------------------------+
+|      0       |          成功          |
+|   EACCESS    |        权限不足        |
+|    ELOOP     | 解析path时遇到路径循环 |
+| ENAMETOOLONG |       路径名过长       |
+|    ENOENT    |  目标文件或目录不存在  |
+|    ENODIR    |  检索期间发现非目录项  |
+|    ENOMEM    |      系统内存不足      |
+|    EFAULT    |       错误的地址       |
+| ENAMETOOLONG |        路径过长        |
++--------------+------------------------+
+ */
+uint64_t sys_chdir(struct pt_regs *regs)
+{
+    char *dest_path = (char *)regs->r8;
+    // kdebug("dest_path=%s", dest_path);
+    // 检查目标路径是否为NULL
+    if (dest_path == NULL)
+        return -EFAULT;
+
+    // 计算输入的路径长度
+    int dest_path_len = strnlen_user(dest_path, PAGE_4K_SIZE);
+
+
+    // 长度小于等于0
+    if (dest_path_len <= 0)
+        return -EFAULT;
+    else if (dest_path_len >= PAGE_4K_SIZE)
+        return -ENAMETOOLONG;
+
+    // 为路径字符串申请空间
+    char *path = kmalloc(dest_path_len + 1, 0);
+    // 系统内存不足
+    if (path == NULL)
+        return -ENOMEM;
+
+    memset(path, 0, dest_path_len + 1);
+
+    // 将字符串从用户空间拷贝进来, +1是为了拷贝结尾的\0
+    strncpy_from_user(path, dest_path, dest_path_len + 1);
+
+
+    struct vfs_dir_entry_t *dentry = vfs_path_walk(path, 0);
+
+    kfree(path);
+
+    if (dentry == NULL)
+        return -ENOENT;
+
+    // 目标不是目录
+    if (dentry->dir_inode->attribute != VFS_ATTR_DIR)
+        return -ENOTDIR;
+
+    return 0;
+}
+
 ul sys_ahci_end_req(struct pt_regs *regs)
 {
     ahci_end_request();
@@ -483,5 +546,6 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
         [9] = sys_brk,
         [10] = sys_sbrk,
         [11] = sys_reboot,
-        [12 ... 254] = system_call_not_exists,
+        [12] = sys_chdir,
+        [13 ... 254] = system_call_not_exists,
         [255] = sys_ahci_end_req};

+ 1 - 0
kernel/syscall/syscall_num.h

@@ -21,5 +21,6 @@
 #define SYS_BRK 9
 #define SYS_SBRK 10
 #define SYS_REBOOT 11   // 重启
+#define SYS_CHDIR 12    // 切换工作目录
 
 #define SYS_AHCI_END_REQ 255    // AHCI DMA请求结束end_request的系统调用

+ 4 - 1
user/apps/shell/Makefile

@@ -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

+ 119 - 3
user/apps/shell/cmd.c

@@ -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);
 }
 
 /**

+ 3 - 0
user/apps/shell/cmd.h

@@ -1,5 +1,8 @@
 #pragma once
 
+// cwd字符串的最大大小
+#define SHELL_CWD_MAX_SIZE  256
+
 /**
  * @brief shell内建命令结构体
  * 

+ 23 - 0
user/apps/shell/cmd_help.c

@@ -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 - 0
user/apps/shell/cmd_help.h

@@ -0,0 +1,10 @@
+#pragma once
+
+#include "cmd.h"
+void shell_help();
+
+/**
+ * @brief cd命令的帮助信息
+ * 
+ */
+void shell_help_cd();

+ 19 - 13
user/apps/shell/shell.c

@@ -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';
 

+ 5 - 2
user/libs/libc/Makefile

@@ -5,7 +5,7 @@ CFLAGS += -I .
 libc_sub_dirs=math
 
 
-libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o
+libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o
 	@list='$(libc_sub_dirs)'; for subdir in $$list; do \
     		echo "make all in $$subdir";\
     		cd $$subdir;\
@@ -32,4 +32,7 @@ stdlib.o: stdlib.c
 	gcc $(CFLAGS) -c stdlib.c -o stdlib.o
 	
 ctype.o: ctype.c
-	gcc $(CFLAGS) -c ctype.c -o ctype.o
+	gcc $(CFLAGS) -c ctype.c -o ctype.o
+
+string.o: string.c
+	gcc $(CFLAGS) -c string.c -o string.o

+ 10 - 5
user/libs/libc/malloc.c

@@ -268,7 +268,7 @@ static void malloc_insert_free_list(malloc_mem_chunk_t *ck)
  */
 void *malloc(ssize_t size)
 {
-
+    // printf("malloc\n");
     // 计算需要分配的块的大小
     if (size + sizeof(uint64_t) <= sizeof(malloc_mem_chunk_t))
         size = sizeof(malloc_mem_chunk_t);
@@ -281,6 +281,7 @@ void *malloc(ssize_t size)
     if (ck == NULL) // 没有空闲块
     {
 
+        // printf("no free blocks\n");
         // 尝试合并空闲块
         malloc_merge_free_chunk();
         ck = malloc_query_free_chunk_bf(size);
@@ -288,10 +289,12 @@ void *malloc(ssize_t size)
         // 找到了合适的块
         if (ck)
             goto found;
+        
+        // printf("before enlarge\n");
         // 找不到合适的块,扩容堆区域
-
         if (malloc_enlarge(size) == -ENOMEM)
             return (void *)-ENOMEM; // 内存不足
+        
 
         malloc_merge_free_chunk(); // 扩容后运行合并,否则会导致碎片
 
@@ -304,6 +307,7 @@ found:;
     // printf("ck = %#018lx\n", (uint64_t)ck);
     if (ck == NULL)
         return (void *)-ENOMEM;
+    // printf("ck->prev=%#018lx ck->next=%#018lx\n", ck->prev, ck->next);
     // 分配空闲块
     // 从空闲链表取出
     if (ck->prev == NULL) // 当前是链表的第一个块
@@ -321,6 +325,7 @@ found:;
     // 当前块剩余的空间还能容纳多一个结点的空间,则分裂当前块
     if ((int64_t)(ck->length) - size > sizeof(malloc_mem_chunk_t))
     {
+        // printf("seperate\n");
         malloc_mem_chunk_t *new_ck = (malloc_mem_chunk_t *)(((uint64_t)ck) + size);
         new_ck->length = ck->length - size;
         new_ck->prev = new_ck->next = NULL;
@@ -328,7 +333,7 @@ found:;
         ck->length = size;
         malloc_insert_free_list(new_ck);
     }
-
+    // printf("malloc done: %#018lx, length=%#018lx\n", ((uint64_t)ck + sizeof(uint64_t)), ck->length);
     // 此时链表结点的指针的空间被分配出去
     return (void *)((uint64_t)ck + sizeof(uint64_t));
 }
@@ -367,13 +372,13 @@ static void release_brk()
  *
  * @param ptr 堆内存的指针
  */
-void free(void *ptr)    
+void free(void *ptr)
 {
     // 找到结点(此时prev和next都处于未初始化的状态)
     malloc_mem_chunk_t *ck = (malloc_mem_chunk_t *)((uint64_t)ptr - sizeof(uint64_t));
     // printf("free(): addr = %#018lx\t len=%#018lx\n", (uint64_t)ck, ck->length);
     count_last_free_size += ck->length;
-    
+
     malloc_insert_free_list(ck);
 
     if (count_last_free_size > PAGE_2M_SIZE)

+ 109 - 0
user/libs/libc/string.c

@@ -0,0 +1,109 @@
+#include "string.h"
+
+size_t strlen(const char *s)
+{
+    register int __res = 0;
+    while (s[__res] != '\0')
+    {
+        ++__res;
+    }
+    return __res;
+}
+
+int strcmp(const char *FirstPart, const char *SecondPart)
+{
+    register int __res;
+    __asm__ __volatile__("cld	\n\t"
+                         "1:	\n\t"
+                         "lodsb	\n\t"
+                         "scasb	\n\t"
+                         "jne	2f	\n\t"
+                         "testb	%%al,	%%al	\n\t"
+                         "jne	1b	\n\t"
+                         "xorl	%%eax,	%%eax	\n\t"
+                         "jmp	3f	\n\t"
+                         "2:	\n\t"
+                         "movl	$1,	%%eax	\n\t"
+                         "jl	3f	\n\t"
+                         "negl	%%eax	\n\t"
+                         "3:	\n\t"
+                         : "=a"(__res)
+                         : "D"(FirstPart), "S"(SecondPart)
+                         :);
+    return __res;
+}
+
+void *memset(void *dst, unsigned char C, uint64_t size)
+{
+
+    int d0, d1;
+    unsigned long tmp = C * 0x0101010101010101UL;
+    __asm__ __volatile__("cld	\n\t"
+                         "rep	\n\t"
+                         "stosq	\n\t"
+                         "testb	$4, %b3	\n\t"
+                         "je	1f	\n\t"
+                         "stosl	\n\t"
+                         "1:\ttestb	$2, %b3	\n\t"
+                         "je	2f\n\t"
+                         "stosw	\n\t"
+                         "2:\ttestb	$1, %b3	\n\t"
+                         "je	3f	\n\t"
+                         "stosb	\n\t"
+                         "3:	\n\t"
+                         : "=&c"(d0), "=&D"(d1)
+                         : "a"(tmp), "q"(size), "0"(size / 8), "1"(dst)
+                         : "memory");
+    return dst;
+}
+
+/**
+ * @brief 拷贝指定字节数的字符串
+ * 
+ * @param dst 目标地址
+ * @param src 源字符串
+ * @param Count 字节数
+ * @return char* 
+ */
+char *strncpy(char *dst, char *src, long Count)
+{
+    __asm__ __volatile__("cld	\n\t"
+                         "1:	\n\t"
+                         "decq	%2	\n\t"
+                         "js	2f	\n\t"
+                         "lodsb	\n\t"
+                         "stosb	\n\t"
+                         "testb	%%al,	%%al	\n\t"
+                         "jne	1b	\n\t"
+                         "rep	\n\t"
+                         "stosb	\n\t"
+                         "2:	\n\t"
+                         :
+                         : "S"(src), "D"(dst), "c"(Count)
+                         : "ax", "memory");
+    return dst;
+}
+
+/**
+ * @brief 拼接两个字符串(将src接到dest末尾)
+ * 
+ * @param dest 目标串
+ * @param src 源串
+ * @return char* 
+ */
+char *strcat(char *dest, const char *src)
+{
+    unsigned int dest_size = strlen(dest);
+    unsigned int src_size = strlen(src);
+
+    char *d = dest;
+
+    for (size_t i = 0; i < src_size; i++)
+    {
+        d[dest_size + i] = src[i];
+    }
+
+    d[dest_size + src_size] = '\0';
+
+    return dest;
+}

+ 28 - 56
user/libs/libc/string.h

@@ -2,40 +2,14 @@
 
 #include <libc/sys/types.h>
 
-void *memset(void *dst, unsigned char C, uint64_t size)
-{
-
-    int d0, d1;
-    unsigned long tmp = C * 0x0101010101010101UL;
-    __asm__ __volatile__("cld	\n\t"
-                         "rep	\n\t"
-                         "stosq	\n\t"
-                         "testb	$4, %b3	\n\t"
-                         "je	1f	\n\t"
-                         "stosl	\n\t"
-                         "1:\ttestb	$2, %b3	\n\t"
-                         "je	2f\n\t"
-                         "stosw	\n\t"
-                         "2:\ttestb	$1, %b3	\n\t"
-                         "je	3f	\n\t"
-                         "stosb	\n\t"
-                         "3:	\n\t"
-                         : "=&c"(d0), "=&D"(d1)
-                         : "a"(tmp), "q"(size), "0"(size / 8), "1"(dst)
-                         : "memory");
-    return dst;
-}
-
-size_t strlen(const char *s)
-{
-    register size_t __res = 0;
-    while (s[__res] != '\0')
-    {
-        ++__res;
-    }
-    return __res;
-}
-
+void *memset(void *dst, unsigned char C, uint64_t size);
+/**
+ * @brief 获取字符串的大小
+ *
+ * @param s 字符串
+ * @return size_t 大小
+ */
+size_t strlen(const char *s);
 
 /*
         比较字符串 FirstPart and SecondPart
@@ -44,25 +18,23 @@ size_t strlen(const char *s)
         FirstPart < SecondPart => -1
 */
 
-int strcmp(const char *FirstPart, const char *SecondPart)
-{
-    register int __res;
-    __asm__ __volatile__("cld	\n\t"
-                         "1:	\n\t"
-                         "lodsb	\n\t"
-                         "scasb	\n\t"
-                         "jne	2f	\n\t"
-                         "testb	%%al,	%%al	\n\t"
-                         "jne	1b	\n\t"
-                         "xorl	%%eax,	%%eax	\n\t"
-                         "jmp	3f	\n\t"
-                         "2:	\n\t"
-                         "movl	$1,	%%eax	\n\t"
-                         "jl	3f	\n\t"
-                         "negl	%%eax	\n\t"
-                         "3:	\n\t"
-                         : "=a"(__res)
-                         : "D"(FirstPart), "S"(SecondPart)
-                         :);
-    return __res;
-}
+int strcmp(const char *FirstPart, const char *SecondPart);
+
+/**
+ * @brief 拷贝指定字节数的字符串
+ *
+ * @param dst 目标地址
+ * @param src 源字符串
+ * @param Count 字节数
+ * @return char*
+ */
+char *strncpy(char *dst, char *src, long Count);
+
+/**
+ * @brief 拼接两个字符串(将src接到dest末尾)
+ *
+ * @param dest 目标串
+ * @param src 源串
+ * @return char*
+ */
+char *strcat(char *dest, const char *src);

+ 30 - 0
user/libs/libc/unistd.c

@@ -2,6 +2,7 @@
 #include <libsystem/syscall.h>
 #include <libc/errno.h>
 #include <libc/stdio.h>
+#include <libc/stddef.h>
 
 /**
  * @brief 关闭文件接口
@@ -105,4 +106,33 @@ void *sbrk(int64_t increment)
         errno = 0;
         return (void *)retval;
     }
+}
+
+/**
+ * @brief 切换当前工作目录
+ *
+ * @param dest_path 目标目录
+ * @return int64_t 成功:0,失败:负值(错误码)
+ */
+int64_t chdir(char *dest_path)
+{
+    if (dest_path == NULL)
+    {
+        errno = -EFAULT;
+        return -1;
+    }
+    else
+    {
+        int retval = syscall_invoke(SYS_CHDIR, (uint64_t)dest_path, 0,0,0,0,0,0,0);
+        if(retval == 0)
+        {
+            errno = 0;
+            return 0;
+        }
+        else
+        {
+            errno = retval;
+            return -1;
+        }
+    }
 }

+ 14 - 11
user/libs/libc/unistd.h

@@ -2,11 +2,6 @@
 #include <stdint.h>
 #include <libc/sys/types.h>
 
-
-
-
-
-
 /**
  * @brief 关闭文件接口
  *
@@ -47,15 +42,15 @@ off_t lseek(int fd, off_t offset, int whence);
 
 /**
  * @brief fork当前进程
- * 
- * @return pid_t 
+ *
+ * @return pid_t
  */
 pid_t fork(void);
 
 /**
  * @brief fork当前进程,但是与父进程共享VM、flags、fd
- * 
- * @return pid_t 
+ *
+ * @return pid_t
  */
 pid_t vfork(void);
 
@@ -72,8 +67,16 @@ uint64_t brk(uint64_t end_brk);
 
 /**
  * @brief 将堆内存空间加上offset(注意,该系统调用只应在普通进程中调用,而不能是内核线程)
- * 
+ *
  * @param increment offset偏移量
  * @return uint64_t the previous program break
  */
-void * sbrk(int64_t increment);
+void *sbrk(int64_t increment);
+
+/**
+ * @brief 切换当前工作目录
+ *
+ * @param dest_path 目标目录
+ * @return int64_t 成功:0,失败:负值(错误码)
+ */
+int64_t chdir(char *dest_path);

+ 1 - 0
user/libs/libsystem/syscall.h

@@ -15,6 +15,7 @@
 #define SYS_BRK 9
 #define SYS_SBRK 10
 #define SYS_REBOOT 11
+#define SYS_CHDIR 12    // 切换工作目录
 
 /**
  * @brief 用户态系统调用函数