mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
🆕 cd命令
This commit is contained in:
parent
8bd7b64a0b
commit
37669ebf87
@ -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};
|
||||
|
@ -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的系统调用
|
@ -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';
|
||||
|
||||
|
@ -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
|
@ -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
user/libs/libc/string.c
Normal file
109
user/libs/libc/string.c
Normal file
@ -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;
|
||||
}
|
@ -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);
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define SYS_BRK 9
|
||||
#define SYS_SBRK 10
|
||||
#define SYS_REBOOT 11
|
||||
#define SYS_CHDIR 12 // 切换工作目录
|
||||
|
||||
/**
|
||||
* @brief 用户态系统调用函数
|
||||
|
Loading…
x
Reference in New Issue
Block a user