mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 20:36:48 +00:00
🆕 完成了ls的功能
This commit is contained in:
parent
a4157bb4a7
commit
9ee6d33318
11
kernel/common/dirent.h
Normal file
11
kernel/common/dirent.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common/miniLibc/sys/types.h>
|
||||||
|
struct dirent
|
||||||
|
{
|
||||||
|
ino_t d_ino; // 文件序列号
|
||||||
|
off_t d_off; // dir偏移量
|
||||||
|
unsigned short d_reclen; // 目录下的记录数
|
||||||
|
unsigned char d_type; // entry的类型
|
||||||
|
char d_name[]; // 文件entry的名字(是一个零长度的数组)
|
||||||
|
};
|
@ -1,5 +1,8 @@
|
|||||||
#include "VFS.h"
|
#include "VFS.h"
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
|
#include <common/dirent.h>
|
||||||
|
#include <common/errno.h>
|
||||||
|
#include <mm/mm.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
|
|
||||||
// 为filesystem_type_t结构体实例化一个链表头
|
// 为filesystem_type_t结构体实例化一个链表头
|
||||||
@ -138,9 +141,27 @@ struct vfs_dir_entry_t *vfs_path_walk(char *path, uint64_t flags)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 填充dentry
|
* @brief 填充dentry
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int vfs_fill_dentry(void *buf, ino_t d_ino, char *name, int namelen, unsigned char type, off_t offset)
|
int vfs_fill_dentry(void *buf, ino_t d_ino, char *name, int namelen, unsigned char type, off_t offset)
|
||||||
{
|
{
|
||||||
|
struct dirent *dent = (struct dirent *)buf;
|
||||||
|
|
||||||
|
// 如果尝试访问内核空间,则返回错误
|
||||||
|
if (!(verify_area((uint64_t)buf, sizeof(struct dirent) + namelen)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
// ====== 填充dirent结构体 =====
|
||||||
|
memset(buf, 0, sizeof(struct dirent) + namelen);
|
||||||
|
|
||||||
|
memcpy(dent->d_name, name, namelen);
|
||||||
|
dent->d_name[namelen] = '\0';
|
||||||
|
// 暂时不显示目录下的记录数
|
||||||
|
dent->d_reclen = 0;
|
||||||
|
dent->d_ino = d_ino;
|
||||||
|
dent->d_off = offset;
|
||||||
|
dent->d_type = type;
|
||||||
|
|
||||||
|
// 返回dirent的总大小
|
||||||
|
return sizeof(struct dirent) + namelen;
|
||||||
}
|
}
|
@ -930,6 +930,8 @@ int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t dentry_type = 0; // 传递给filler的dentry类型数据
|
||||||
|
|
||||||
char *dir_name = NULL;
|
char *dir_name = NULL;
|
||||||
int name_len = 0;
|
int name_len = 0;
|
||||||
// ==== 此时已经将文件夹的目录项起始簇的簇号读取到cluster变量中 ===
|
// ==== 此时已经将文件夹的目录项起始簇的簇号读取到cluster变量中 ===
|
||||||
@ -1012,6 +1014,7 @@ int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t f
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 读取目录项成功,返回
|
// 读取目录项成功,返回
|
||||||
|
dentry_type = dentry->DIR_Attr;
|
||||||
goto find_dir_success;
|
goto find_dir_success;
|
||||||
}
|
}
|
||||||
else // 不存在长目录项
|
else // 不存在长目录项
|
||||||
@ -1035,7 +1038,10 @@ int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t f
|
|||||||
|
|
||||||
// 如果当前短目录项为文件夹,则直接返回,不需要读取扩展名
|
// 如果当前短目录项为文件夹,则直接返回,不需要读取扩展名
|
||||||
if (dentry->DIR_Attr & ATTR_DIRECTORY)
|
if (dentry->DIR_Attr & ATTR_DIRECTORY)
|
||||||
|
{
|
||||||
|
dentry_type = dentry->DIR_Attr;
|
||||||
goto find_dir_success;
|
goto find_dir_success;
|
||||||
|
}
|
||||||
|
|
||||||
// 是文件,增加 .
|
// 是文件,增加 .
|
||||||
dir_name[name_len++] = '.';
|
dir_name[name_len++] = '.';
|
||||||
@ -1056,6 +1062,7 @@ int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t f
|
|||||||
if (total_len == 8) // 没有扩展名
|
if (total_len == 8) // 没有扩展名
|
||||||
dir_name[--name_len] = '\0';
|
dir_name[--name_len] = '\0';
|
||||||
|
|
||||||
|
dentry_type = dentry->DIR_Attr;
|
||||||
goto find_dir_success;
|
goto find_dir_success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1072,7 +1079,12 @@ find_dir_success:;
|
|||||||
// 将文件夹位置坐标加32(即指向下一个目录项)
|
// 将文件夹位置坐标加32(即指向下一个目录项)
|
||||||
file_ptr->position += 32;
|
file_ptr->position += 32;
|
||||||
// todo: 计算ino_t
|
// todo: 计算ino_t
|
||||||
return filler(dirent, 0, dir_name, name_len, 0, 0);
|
if(dentry_type & ATTR_DIRECTORY)
|
||||||
|
dentry_type = VFS_ATTR_DIR;
|
||||||
|
else
|
||||||
|
dentry_type = VFS_ATTR_FILE;
|
||||||
|
|
||||||
|
return filler(dirent, 0, dir_name, name_len, dentry_type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vfs_inode_operations_t fat32_inode_ops =
|
struct vfs_inode_operations_t fat32_inode_ops =
|
||||||
|
@ -110,7 +110,7 @@ uint64_t sys_open(struct pt_regs *regs)
|
|||||||
|
|
||||||
char *filename = (char *)(regs->r8);
|
char *filename = (char *)(regs->r8);
|
||||||
int flags = (int)(regs->r9);
|
int flags = (int)(regs->r9);
|
||||||
kdebug("filename=%s", filename);
|
// kdebug("filename=%s", filename);
|
||||||
|
|
||||||
long path_len = strnlen_user(filename, PAGE_4K_SIZE) + 1;
|
long path_len = strnlen_user(filename, PAGE_4K_SIZE) + 1;
|
||||||
|
|
||||||
@ -134,10 +134,10 @@ uint64_t sys_open(struct pt_regs *regs)
|
|||||||
// 寻找文件
|
// 寻找文件
|
||||||
struct vfs_dir_entry_t *dentry = vfs_path_walk(path, 0);
|
struct vfs_dir_entry_t *dentry = vfs_path_walk(path, 0);
|
||||||
|
|
||||||
if (dentry != NULL)
|
// if (dentry != NULL)
|
||||||
printk_color(ORANGE, BLACK, "Found %s\nDIR_FstClus:%#018lx\tDIR_FileSize:%#018lx\n", path, ((struct fat32_inode_info_t *)(dentry->dir_inode->private_inode_info))->first_clus, dentry->dir_inode->file_size);
|
// printk_color(ORANGE, BLACK, "Found %s\nDIR_FstClus:%#018lx\tDIR_FileSize:%#018lx\n", path, ((struct fat32_inode_info_t *)(dentry->dir_inode->private_inode_info))->first_clus, dentry->dir_inode->file_size);
|
||||||
else
|
// else
|
||||||
printk_color(ORANGE, BLACK, "Can`t find file\n");
|
// printk_color(ORANGE, BLACK, "Can`t find file\n");
|
||||||
|
|
||||||
kfree(path);
|
kfree(path);
|
||||||
if (dentry == NULL)
|
if (dentry == NULL)
|
||||||
@ -236,7 +236,7 @@ uint64_t sys_close(struct pt_regs *regs)
|
|||||||
{
|
{
|
||||||
int fd_num = (int)regs->r8;
|
int fd_num = (int)regs->r8;
|
||||||
|
|
||||||
kdebug("sys close: fd=%d", fd_num);
|
// kdebug("sys close: fd=%d", fd_num);
|
||||||
// 校验文件描述符范围
|
// 校验文件描述符范围
|
||||||
if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM)
|
if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <libc/unistd.h>
|
#include <libc/unistd.h>
|
||||||
#include <libc/stdlib.h>
|
#include <libc/stdlib.h>
|
||||||
|
|
||||||
|
#include <libc/dirent.h>
|
||||||
|
|
||||||
#include "cmd_help.h"
|
#include "cmd_help.h"
|
||||||
|
|
||||||
// 当前工作目录(在main_loop中初始化)
|
// 当前工作目录(在main_loop中初始化)
|
||||||
@ -152,7 +154,7 @@ int shell_cmd_cd(int argc, char **argv)
|
|||||||
if (argv[1][0] == '.' && argv[1][1] == '/') // 相对路径
|
if (argv[1][0] == '.' && argv[1][1] == '/') // 相对路径
|
||||||
dest_offset = 2;
|
dest_offset = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_len = current_dir_len + dest_len - dest_offset;
|
int new_len = current_dir_len + dest_len - dest_offset;
|
||||||
// ======进入相对路径=====
|
// ======进入相对路径=====
|
||||||
if (new_len >= SHELL_CWD_MAX_SIZE - 1)
|
if (new_len >= SHELL_CWD_MAX_SIZE - 1)
|
||||||
@ -201,6 +203,34 @@ done:;
|
|||||||
// todo:
|
// todo:
|
||||||
int shell_cmd_ls(int argc, char **argv)
|
int shell_cmd_ls(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
struct DIR *dir = opendir(shell_current_path);
|
||||||
|
|
||||||
|
if (dir == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct dirent *buf = NULL;
|
||||||
|
// printf("dir=%#018lx\n", dir);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
buf = readdir(dir);
|
||||||
|
if(buf == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int color = COLOR_WHITE;
|
||||||
|
if(buf->d_type & VFS_ATTR_DIR)
|
||||||
|
color = COLOR_YELLOW;
|
||||||
|
else if(buf->d_type & VFS_ATTR_FILE)
|
||||||
|
color = COLOR_INDIGO;
|
||||||
|
|
||||||
|
char output_buf[256] = {0};
|
||||||
|
|
||||||
|
sprintf(output_buf, "%s ", buf->d_name);
|
||||||
|
put_string(output_buf, color, COLOR_BLACK);
|
||||||
|
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
closedir(dir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ CFLAGS += -I .
|
|||||||
libc_sub_dirs=math
|
libc_sub_dirs=math
|
||||||
|
|
||||||
|
|
||||||
libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o
|
libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o dirent.o
|
||||||
@list='$(libc_sub_dirs)'; for subdir in $$list; do \
|
@list='$(libc_sub_dirs)'; for subdir in $$list; do \
|
||||||
echo "make all in $$subdir";\
|
echo "make all in $$subdir";\
|
||||||
cd $$subdir;\
|
cd $$subdir;\
|
||||||
|
@ -17,10 +17,15 @@ struct DIR *opendir(const char *path)
|
|||||||
{
|
{
|
||||||
int fd = open(path, O_DIRECTORY);
|
int fd = open(path, O_DIRECTORY);
|
||||||
if (fd < 0) // 目录打开失败
|
if (fd < 0) // 目录打开失败
|
||||||
|
{
|
||||||
|
printf("Failed to open dir\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
// printf("open dir: %s\n", path);
|
||||||
|
|
||||||
// 分配DIR结构体
|
// 分配DIR结构体
|
||||||
struct DIR *dirp = (struct DIR *)malloc(sizeof(struct DIR));
|
struct DIR *dirp = (struct DIR *)malloc(sizeof(struct DIR));
|
||||||
|
// printf("dirp = %#018lx", dirp);
|
||||||
memset(dirp, 0, sizeof(struct DIR));
|
memset(dirp, 0, sizeof(struct DIR));
|
||||||
dirp->fd = fd;
|
dirp->fd = fd;
|
||||||
dirp->buf_len = DIR_BUF_SIZE;
|
dirp->buf_len = DIR_BUF_SIZE;
|
||||||
@ -59,11 +64,13 @@ int64_t getdents(int fd, struct dirent *dirent, long count)
|
|||||||
* @param dir
|
* @param dir
|
||||||
* @return struct dirent*
|
* @return struct dirent*
|
||||||
*/
|
*/
|
||||||
struct dirent *reaaddir(struct DIR *dir)
|
struct dirent *readdir(struct DIR *dir)
|
||||||
{
|
{
|
||||||
memset(dir, 0, DIR_BUF_SIZE);
|
// printf("dir->buf = %#018lx\n", (dir->buf));
|
||||||
|
memset((dir->buf), 0, DIR_BUF_SIZE);
|
||||||
|
// printf("memeset_ok\n");
|
||||||
int len = getdents(dir->fd, (struct dirent *)dir->buf, DIR_BUF_SIZE);
|
int len = getdents(dir->fd, (struct dirent *)dir->buf, DIR_BUF_SIZE);
|
||||||
|
// printf("len=%d\n", len);
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
return (struct dirent *)dir->buf;
|
return (struct dirent *)dir->buf;
|
||||||
else
|
else
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <libc/sys/types.h>
|
#include <libc/sys/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 目录项的属性(copy from vfs.h)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define VFS_ATTR_FILE (1UL << 0)
|
||||||
|
#define VFS_ATTR_DIR (1UL << 1)
|
||||||
|
#define VFS_ATTR_DEVICE (1UL << 2)
|
||||||
|
|
||||||
#define DIR_BUF_SIZE 256
|
#define DIR_BUF_SIZE 256
|
||||||
/**
|
/**
|
||||||
* @brief 文件夹结构体
|
* @brief 文件夹结构体
|
||||||
@ -22,7 +31,7 @@ struct dirent
|
|||||||
off_t d_off; // dir偏移量
|
off_t d_off; // dir偏移量
|
||||||
unsigned short d_reclen; // 目录下的记录数
|
unsigned short d_reclen; // 目录下的记录数
|
||||||
unsigned char d_type; // entry的类型
|
unsigned char d_type; // entry的类型
|
||||||
char d_name[256]; // 文件entry的名字
|
char d_name[]; // 文件entry的名字(是一个零长数组)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,4 +63,4 @@ int closedir(struct DIR *dirp);
|
|||||||
* @param dir
|
* @param dir
|
||||||
* @return struct dirent*
|
* @return struct dirent*
|
||||||
*/
|
*/
|
||||||
struct dirent* reaaddir(struct DIR* dir);
|
struct dirent* readdir(struct DIR* dir);
|
Loading…
x
Reference in New Issue
Block a user