Implement read_dir_entry () VFS op, CE add ls command
This commit is contained in:
49
ce/ce.c
49
ce/ce.c
@@ -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) {
|
||||
(void)tokens;
|
||||
|
||||
printf ("Available commands:\n");
|
||||
printf ("\techo <word1> <word2> <word3> ...\n");
|
||||
printf ("\thelp\n");
|
||||
printf ("\tcat <file path>\n");
|
||||
printf ("echo <word1> <word2> <word3> ...\n");
|
||||
printf ("help\n");
|
||||
printf ("cat <file path>\n");
|
||||
printf ("ls <directory path>\n");
|
||||
}
|
||||
|
||||
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);
|
||||
} else if (strcmp (cmd_token->buffer, "cat") == 0) {
|
||||
cmd_cat (tokens->next);
|
||||
} else if (strcmp (cmd_token->buffer, "ls") == 0) {
|
||||
cmd_ls (tokens->next);
|
||||
} else {
|
||||
printf ("ERROR: unknown command '%s'\n", cmd_token->buffer);
|
||||
}
|
||||
|
||||
10
include/dir_entry.h
Normal file
10
include/dir_entry.h
Normal 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
|
||||
@@ -16,5 +16,7 @@
|
||||
#define ST_EXEC_ERROR 12
|
||||
#define ST_MOUNT_ERROR 13
|
||||
#define ST_TRY_AGAIN 14
|
||||
#define ST_NOT_DIR 15
|
||||
#define ST_DIR_NO_ENTRIES 16
|
||||
|
||||
#endif // _M_STATUS_H
|
||||
|
||||
@@ -22,5 +22,6 @@
|
||||
#define SYS_MAIL_RECEIVE 19
|
||||
#define SYS_GET_PROCGROUP 20
|
||||
#define SYS_GET_EXEC_PID 21
|
||||
#define SYS_READ_DIR_ENTRY 22
|
||||
|
||||
#endif // _M_SYSCALL_DEFS_H
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <fs/vfs.h>
|
||||
#include <libk/align.h>
|
||||
#include <libk/minmax.h>
|
||||
#include <libk/printf.h>
|
||||
#include <libk/std.h>
|
||||
#include <libk/string.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) {
|
||||
(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);
|
||||
|
||||
if (filename == NULL)
|
||||
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)
|
||||
return -ST_NOT_FOUND;
|
||||
@@ -131,6 +144,7 @@ int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* de
|
||||
|
||||
return ST_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
|
||||
size_t size) {
|
||||
@@ -150,3 +164,30 @@ int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, si
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <desc.h>
|
||||
#include <device/device.h>
|
||||
#include <dir_entry.h>
|
||||
#include <libk/std.h>
|
||||
#include <proc/proc.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,
|
||||
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
|
||||
|
||||
@@ -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.describe = &tarfs_describe;
|
||||
volume->driver_ops.read = &tarfs_read;
|
||||
volume->driver_ops.read_dir_entry = &tarfs_read_dir_entry;
|
||||
} break;
|
||||
default: {
|
||||
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,
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int vfs_describe (struct proc* proc, const char* volume_name, const char* path, struct desc* desc,
|
||||
struct reschedule_ctx* rctx) {
|
||||
int vfs_describe (struct proc* proc, const char* volume_name, const char* path, struct desc* desc) {
|
||||
struct vfs_volume* volume = vfs_find_volume (volume_name);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
memset (&volume_table, 0, sizeof (volume_table));
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <desc.h>
|
||||
#include <device/device.h>
|
||||
#include <dir_entry.h>
|
||||
#include <libk/hash.h>
|
||||
#include <libk/list.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,
|
||||
size_t size);
|
||||
|
||||
int (*read_dir_entry) (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
|
||||
size_t entry_num);
|
||||
} driver_ops;
|
||||
struct device* back_device;
|
||||
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_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,
|
||||
struct reschedule_ctx* rctx);
|
||||
int vfs_describe (struct proc* proc, const char* volume, const char* path, struct desc* desc);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char*
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
@@ -149,7 +149,7 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char*
|
||||
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);
|
||||
vfs_volume_close (proc1, volume, rctx);
|
||||
return NULL;
|
||||
|
||||
@@ -371,7 +371,7 @@ DEFINE_SYSCALL (sys_read) {
|
||||
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||
|
||||
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);
|
||||
|
||||
return SYSRESULT (ret);
|
||||
@@ -401,7 +401,7 @@ DEFINE_SYSCALL (sys_describe) {
|
||||
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||
|
||||
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);
|
||||
|
||||
return SYSRESULT (ret);
|
||||
@@ -419,6 +419,37 @@ DEFINE_SYSCALL (sys_get_procgroup) {
|
||||
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) */
|
||||
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_GET_PROCGROUP] = &sys_get_procgroup,
|
||||
[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) {
|
||||
|
||||
@@ -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_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);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _LIBMSL_M_SYSTEM_H
|
||||
|
||||
#include <desc.h>
|
||||
#include <dir_entry.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -77,4 +78,7 @@ int get_procgroup (int pid);
|
||||
/* get PID of process, which exec'ed the current process */
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user