Implement read_dir_entry () VFS op, CE add ls command

This commit is contained in:
2026-02-25 16:25:43 +01:00
parent 704db2dfa4
commit 29bbcea435
12 changed files with 189 additions and 23 deletions

49
ce/ce.c
View File

@@ -108,13 +108,54 @@ static void cmd_cat (struct list_node_link* tokens) {
} }
} }
static void cmd_ls (struct list_node_link* tokens) {
if (tokens == NULL) {
printf ("ERROR no directory path provided\n");
return;
}
struct token* token = list_entry (tokens, struct token, tokens_link);
struct desc desc;
char volume[VOLUME_MAX];
const char* path;
int ret;
struct dir_entry entry;
if (!path_parse (token->buffer, volume, &path)) {
printf ("ERROR bad path '%s'\n", token->buffer);
return;
}
if ((ret = volume_open (volume)) < 0) {
printf ("ERROR could not open volume '%s': %s\n", volume, str_status[-ret]);
return;
}
describe (path, &desc);
if (desc.type != FS_DIR) {
volume_close ();
}
size_t entries = desc.size;
for (size_t entry_num = 0; entry_num < entries; entry_num++) {
read_dir_entry (path, &entry, entry_num);
describe (entry.path, &desc);
printf ("%-40s%c %-40zu\n", entry.path, (desc.type == FS_DIR ? '*' : ' '), desc.size);
}
volume_close ();
}
static void cmd_help (struct list_node_link* tokens) { static void cmd_help (struct list_node_link* tokens) {
(void)tokens; (void)tokens;
printf ("Available commands:\n"); printf ("Available commands:\n");
printf ("\techo <word1> <word2> <word3> ...\n"); printf ("echo <word1> <word2> <word3> ...\n");
printf ("\thelp\n"); printf ("help\n");
printf ("\tcat <file path>\n"); printf ("cat <file path>\n");
printf ("ls <directory path>\n");
} }
static void exec_tokens (struct list_node_link* tokens) { static void exec_tokens (struct list_node_link* tokens) {
@@ -126,6 +167,8 @@ static void exec_tokens (struct list_node_link* tokens) {
cmd_help (tokens->next); cmd_help (tokens->next);
} else if (strcmp (cmd_token->buffer, "cat") == 0) { } else if (strcmp (cmd_token->buffer, "cat") == 0) {
cmd_cat (tokens->next); cmd_cat (tokens->next);
} else if (strcmp (cmd_token->buffer, "ls") == 0) {
cmd_ls (tokens->next);
} else { } else {
printf ("ERROR: unknown command '%s'\n", cmd_token->buffer); printf ("ERROR: unknown command '%s'\n", cmd_token->buffer);
} }

10
include/dir_entry.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef _DIR_ENTRY_H
#define _DIR_ENTRY_H
#include <path_defs.h>
struct dir_entry {
char path[PATH_MAX];
};
#endif // _DIR_ENTRY_H

View File

@@ -16,5 +16,7 @@
#define ST_EXEC_ERROR 12 #define ST_EXEC_ERROR 12
#define ST_MOUNT_ERROR 13 #define ST_MOUNT_ERROR 13
#define ST_TRY_AGAIN 14 #define ST_TRY_AGAIN 14
#define ST_NOT_DIR 15
#define ST_DIR_NO_ENTRIES 16
#endif // _M_STATUS_H #endif // _M_STATUS_H

View File

@@ -22,5 +22,6 @@
#define SYS_MAIL_RECEIVE 19 #define SYS_MAIL_RECEIVE 19
#define SYS_GET_PROCGROUP 20 #define SYS_GET_PROCGROUP 20
#define SYS_GET_EXEC_PID 21 #define SYS_GET_EXEC_PID 21
#define SYS_READ_DIR_ENTRY 22
#endif // _M_SYSCALL_DEFS_H #endif // _M_SYSCALL_DEFS_H

View File

@@ -4,6 +4,7 @@
#include <fs/vfs.h> #include <fs/vfs.h>
#include <libk/align.h> #include <libk/align.h>
#include <libk/minmax.h> #include <libk/minmax.h>
#include <libk/printf.h>
#include <libk/std.h> #include <libk/std.h>
#include <libk/string.h> #include <libk/string.h>
#include <limine/requests.h> #include <limine/requests.h>
@@ -114,14 +115,26 @@ int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule
} }
int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc) { int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc) {
(void)volume; struct tarfs* tarfs = volume->udata;
if (strncmp (path, "/", PATH_MAX) == 0) {
desc->size = 0;
desc->type = FS_DIR;
for (size_t i = 0; i < TARFS_FILES_MAX; i++) {
if (tarfs->tarfs_files[i].header != NULL) {
desc->size++;
}
}
return ST_OK;
} else {
const char* filename = path_basename (path); const char* filename = path_basename (path);
if (filename == NULL) if (filename == NULL)
return -ST_BAD_PATH; return -ST_BAD_PATH;
struct tar_file* file = tar_get_file ((struct tarfs*)volume->udata, filename); struct tar_file* file = tar_get_file (tarfs, filename);
if (file == NULL) if (file == NULL)
return -ST_NOT_FOUND; return -ST_NOT_FOUND;
@@ -130,6 +143,7 @@ int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* de
desc->type = FS_FILE; desc->type = FS_FILE;
return ST_OK; return ST_OK;
}
} }
int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
@@ -150,3 +164,30 @@ int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, si
return ST_OK; return ST_OK;
} }
int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num) {
struct tarfs* tarfs = volume->udata;
if (strncmp (path, "/", PATH_MAX) != 0) {
return -ST_NOT_DIR;
}
struct tar_file* tar_file = NULL;
size_t entry_counter = 0;
for (size_t i = 0; i < TARFS_FILES_MAX; i++) {
if ((tarfs->tarfs_files[i].header != NULL) && (entry_num == entry_counter)) {
tar_file = &tarfs->tarfs_files[i];
break;
}
entry_counter++;
}
if (tar_file != NULL) {
sprintf (entry->path, "/%s", tar_file->header->filename);
return ST_NOT_DIR;
}
return ST_DIR_NO_ENTRIES;
}

View File

@@ -3,6 +3,7 @@
#include <desc.h> #include <desc.h>
#include <device/device.h> #include <device/device.h>
#include <dir_entry.h>
#include <libk/std.h> #include <libk/std.h>
#include <proc/proc.h> #include <proc/proc.h>
#include <proc/reschedule.h> #include <proc/reschedule.h>
@@ -40,4 +41,7 @@ int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* de
int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size);
int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num);
#endif // _KERNEL_FS_TARFS_H #endif // _KERNEL_FS_TARFS_H

View File

@@ -56,6 +56,7 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device,
volume->driver_ops.mount = &tarfs_mount; volume->driver_ops.mount = &tarfs_mount;
volume->driver_ops.describe = &tarfs_describe; volume->driver_ops.describe = &tarfs_describe;
volume->driver_ops.read = &tarfs_read; volume->driver_ops.read = &tarfs_read;
volume->driver_ops.read_dir_entry = &tarfs_read_dir_entry;
} break; } break;
default: { default: {
free (volume); free (volume);
@@ -147,7 +148,7 @@ int vfs_volume_close (struct proc* proc, const char* volume_name, struct resched
} }
int vfs_read (struct proc* proc, const char* volume_name, const char* path, uint8_t* buffer, int vfs_read (struct proc* proc, const char* volume_name, const char* path, uint8_t* buffer,
size_t off, size_t size, struct reschedule_ctx* rctx) { size_t off, size_t size) {
struct vfs_volume* volume = vfs_find_volume (volume_name); struct vfs_volume* volume = vfs_find_volume (volume_name);
if (volume == NULL) if (volume == NULL)
@@ -165,8 +166,7 @@ int vfs_read (struct proc* proc, const char* volume_name, const char* path, uint
return volume->driver_ops.read (volume, path, buffer, off, size); return volume->driver_ops.read (volume, path, buffer, off, size);
} }
int vfs_describe (struct proc* proc, const char* volume_name, const char* path, struct desc* desc, int vfs_describe (struct proc* proc, const char* volume_name, const char* path, struct desc* desc) {
struct reschedule_ctx* rctx) {
struct vfs_volume* volume = vfs_find_volume (volume_name); struct vfs_volume* volume = vfs_find_volume (volume_name);
if (volume == NULL) if (volume == NULL)
@@ -184,6 +184,25 @@ int vfs_describe (struct proc* proc, const char* volume_name, const char* path,
return volume->driver_ops.describe (volume, path, desc); return volume->driver_ops.describe (volume, path, desc);
} }
int vfs_read_dir_entry (struct proc* proc, const char* volume_name, const char* path,
struct dir_entry* entry, size_t entry_num) {
struct vfs_volume* volume = vfs_find_volume (volume_name);
if (volume == NULL)
return -ST_NOT_FOUND;
spin_lock (&volume->lock);
if (volume->locked && volume->owner != proc) {
spin_unlock (&volume->lock);
return -ST_PERMISSION_ERROR;
}
spin_unlock (&volume->lock);
return volume->driver_ops.read_dir_entry (volume, path, entry, entry_num);
}
void vfs_init (void) { void vfs_init (void) {
memset (&volume_table, 0, sizeof (volume_table)); memset (&volume_table, 0, sizeof (volume_table));

View File

@@ -3,6 +3,7 @@
#include <desc.h> #include <desc.h>
#include <device/device.h> #include <device/device.h>
#include <dir_entry.h>
#include <libk/hash.h> #include <libk/hash.h>
#include <libk/list.h> #include <libk/list.h>
#include <libk/rbtree.h> #include <libk/rbtree.h>
@@ -35,6 +36,9 @@ struct vfs_volume {
int (*read) (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int (*read) (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size);
int (*read_dir_entry) (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num);
} driver_ops; } driver_ops;
struct device* back_device; struct device* back_device;
void* udata void* udata
@@ -53,10 +57,12 @@ int vfs_volume_open (struct proc* proc, const char* volume, struct reschedule_ct
int vfs_volume_close (struct proc* proc, const char* volume, struct reschedule_ctx* rctx); int vfs_volume_close (struct proc* proc, const char* volume, struct reschedule_ctx* rctx);
int vfs_read (struct proc* proc, const char* volume, const char* path, uint8_t* buffer, size_t off, int vfs_read (struct proc* proc, const char* volume, const char* path, uint8_t* buffer, size_t off,
size_t size, struct reschedule_ctx* rctx); size_t size);
int vfs_describe (struct proc* proc, const char* volume, const char* path, struct desc* desc, int vfs_describe (struct proc* proc, const char* volume, const char* path, struct desc* desc);
struct reschedule_ctx* rctx);
int vfs_read_dir_entry (struct proc* proc, const char* volume, const char* path,
struct dir_entry* entry, size_t entry_num);
void vfs_init (void); void vfs_init (void);

View File

@@ -132,7 +132,7 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char*
break; break;
} }
if ((ret = vfs_describe (proc1, volume, path, &desc, rctx)) < 0) { if ((ret = vfs_describe (proc1, volume, path, &desc)) < 0) {
vfs_volume_close (proc1, volume, rctx); vfs_volume_close (proc1, volume, rctx);
return NULL; return NULL;
} }
@@ -149,7 +149,7 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char*
return NULL; return NULL;
} }
if ((ret = vfs_read (proc1, volume, path, temp_buffer, 0, desc.size, rctx)) < 0) { if ((ret = vfs_read (proc1, volume, path, temp_buffer, 0, desc.size)) < 0) {
free (temp_buffer); free (temp_buffer);
vfs_volume_close (proc1, volume, rctx); vfs_volume_close (proc1, volume, rctx);
return NULL; return NULL;

View File

@@ -371,7 +371,7 @@ DEFINE_SYSCALL (sys_read) {
return SYSRESULT (-ST_BAD_ADDRESS_SPACE); return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
spin_lock (&proc->lock); spin_lock (&proc->lock);
int ret = vfs_read (proc, proc->cwv, path, buffer, off, size, rctx); int ret = vfs_read (proc, proc->cwv, path, buffer, off, size);
spin_unlock (&proc->lock); spin_unlock (&proc->lock);
return SYSRESULT (ret); return SYSRESULT (ret);
@@ -401,7 +401,7 @@ DEFINE_SYSCALL (sys_describe) {
return SYSRESULT (-ST_BAD_ADDRESS_SPACE); return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
spin_lock (&proc->lock); spin_lock (&proc->lock);
int ret = vfs_describe (proc, proc->cwv, path, desc, rctx); int ret = vfs_describe (proc, proc->cwv, path, desc);
spin_unlock (&proc->lock); spin_unlock (&proc->lock);
return SYSRESULT (ret); return SYSRESULT (ret);
@@ -419,6 +419,37 @@ DEFINE_SYSCALL (sys_get_procgroup) {
return SYSRESULT (target_proc->procgroup->pgid); return SYSRESULT (target_proc->procgroup->pgid);
} }
/* int read_dir_entry (char* path, struct dir_entry* entry, size_t entry_num) */
DEFINE_SYSCALL (sys_read_dir_entry) {
uintptr_t uvaddr_path = a1;
uintptr_t uvaddr_entry = a2;
size_t entry_num = (size_t)a3;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
uintptr_t out_paddr;
spin_lock (&proc->procgroup->lock);
out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path);
spin_unlock (&proc->procgroup->lock);
if (out_paddr == 0)
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr);
struct dir_entry* entry = sys_get_user_buffer (proc, uvaddr_entry, sizeof (struct dir_entry));
if (entry == NULL)
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
spin_lock (&proc->lock);
int ret = vfs_read_dir_entry (proc, proc->cwv, path, entry, entry_num);
spin_unlock (&proc->lock);
return SYSRESULT (ret);
}
/* int get_exec_pid (void) */ /* int get_exec_pid (void) */
DEFINE_SYSCALL (sys_get_exec_pid) { return SYSRESULT (proc->exec_pid); } DEFINE_SYSCALL (sys_get_exec_pid) { return SYSRESULT (proc->exec_pid); }
@@ -444,6 +475,7 @@ static syscall_handler_func_t handler_table[] = {
[SYS_MAIL_RECEIVE] = &sys_mail_receive, [SYS_MAIL_RECEIVE] = &sys_mail_receive,
[SYS_GET_PROCGROUP] = &sys_get_procgroup, [SYS_GET_PROCGROUP] = &sys_get_procgroup,
[SYS_GET_EXEC_PID] = &sys_get_exec_pid, [SYS_GET_EXEC_PID] = &sys_get_exec_pid,
[SYS_READ_DIR_ENTRY] = &sys_read_dir_entry,
}; };
syscall_handler_func_t syscall_find_handler (int syscall_num) { syscall_handler_func_t syscall_find_handler (int syscall_num) {

View File

@@ -64,3 +64,7 @@ int mail_receive (void* mesg, size_t mesg_size) {
int get_procgroup (int pid) { return (int)do_syscall (SYS_GET_PROCGROUP, pid); } int get_procgroup (int pid) { return (int)do_syscall (SYS_GET_PROCGROUP, pid); }
int get_exec_pid (void) { return (int)do_syscall (SYS_GET_EXEC_PID, 0); } int get_exec_pid (void) { return (int)do_syscall (SYS_GET_EXEC_PID, 0); }
int read_dir_entry (const char* path, struct dir_entry* entry, size_t entry_num) {
return (int)do_syscall (SYS_READ_DIR_ENTRY, path, entry, entry_num);
}

View File

@@ -2,6 +2,7 @@
#define _LIBMSL_M_SYSTEM_H #define _LIBMSL_M_SYSTEM_H
#include <desc.h> #include <desc.h>
#include <dir_entry.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@@ -77,4 +78,7 @@ int get_procgroup (int pid);
/* get PID of process, which exec'ed the current process */ /* get PID of process, which exec'ed the current process */
int get_exec_pid (void); int get_exec_pid (void);
/* Read directory entry */
int read_dir_entry (const char* path, struct dir_entry* entry, size_t entry_num);
#endif // _LIBMSL_M_SYSTEM_H #endif // _LIBMSL_M_SYSTEM_H