From 35d5bed433aff5cfc4ec0237e83228498e42124e Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Thu, 5 Mar 2026 00:38:58 +0100 Subject: [PATCH] CE add mkdir command, implement create_dir () syscall --- ce/interp.c | 27 +++++++++++++++++++++++++++ include/status.h | 1 + include/syscall_defs.h | 1 + kernel/fs/fatfs.c | 7 +++++++ kernel/fs/fatfs.h | 2 ++ kernel/fs/tarfs.c | 5 +++++ kernel/fs/tarfs.h | 2 ++ kernel/fs/vfs.c | 21 +++++++++++++++++++++ kernel/fs/vfs.h | 4 ++++ kernel/syscall/syscall.c | 25 +++++++++++++++++++++++++ libsystem/system.c | 2 ++ libsystem/system.h | 3 +++ 12 files changed, 100 insertions(+) diff --git a/ce/interp.c b/ce/interp.c index c73e549..1b40a95 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -49,6 +49,30 @@ static void mkfile (struct context* context, char** file_paths, size_t files_cou } } +static void mkdir (struct context* context, char** dir_paths, size_t dirs_count) { + char volume[VOLUME_MAX]; + const char* path; + int ret; + + for (size_t i = 0; i < dirs_count; i++) { + const char* dir_path = dir_paths[i]; + + if (!path_parse (dir_path, volume, &path)) { + cprintf (context, "ERROR bad path '%s'\n", dir_path); + continue; + } + + if ((ret = volume_open (volume)) < 0) { + cprintf (context, "ERROR could not open volume '%s': %s\n", volume, str_status[-ret]); + continue; + } + + create_dir (path); + + volume_close (); + } +} + static void cat (struct context* context, char** file_paths, size_t files_count) { char volume[VOLUME_MAX]; const char* path; @@ -153,6 +177,7 @@ static void help (struct context* context) { cprintf (context, "cat \n"); cprintf (context, "ls \n"); cprintf (context, "mkfile \n"); + cprintf (context, "mkdir \n"); cprintf (context, "quit\n"); } @@ -185,6 +210,8 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context) { quit1 (context); } else if (strcmp (cmd->name, "mkfile") == 0) { mkfile (context, cmd->args, cmd->arg_count); + } else if (strcmp (cmd->name, "mkdir") == 0) { + mkdir (context, cmd->args, cmd->arg_count); } else { /* cprintf (context, "ERROR unknown command '%s'\n", cmd->name); */ char volume[VOLUME_MAX]; diff --git a/include/status.h b/include/status.h index 86cca22..df891df 100644 --- a/include/status.h +++ b/include/status.h @@ -21,5 +21,6 @@ #define ST_FORMAT_ERROR 17 #define ST_NOT_DRV 18 #define ST_PARTITION_ERROR 19 +#define ST_CREATE_DIR_ERROR 20 #endif // _M_STATUS_H diff --git a/include/syscall_defs.h b/include/syscall_defs.h index e687a1a..bea4092 100644 --- a/include/syscall_defs.h +++ b/include/syscall_defs.h @@ -27,5 +27,6 @@ #define SYS_WRITE_FILE 24 #define SYS_WAIT_FOR_PID 25 #define SYS_KILL 26 +#define SYS_CREATE_DIR 27 #endif // _M_SYSCALL_DEFS_H diff --git a/kernel/fs/fatfs.c b/kernel/fs/fatfs.c index 32c53f7..83e7782 100644 --- a/kernel/fs/fatfs.c +++ b/kernel/fs/fatfs.c @@ -259,3 +259,10 @@ int fatfs_create_file (struct vfs_volume* volume, const char* path) { fl_fclose (fatfs_ctx, file); return ST_OK; } + +int fatfs_create_dir (struct vfs_volume* volume, const char* path) { + struct fatfs_ctx* fatfs_ctx = volume->udata; + + int r = fl_createdirectory (fatfs_ctx, path); + return r == 0 ? ST_OK : ST_CREATE_DIR_ERROR; +} diff --git a/kernel/fs/fatfs.h b/kernel/fs/fatfs.h index 55259b6..47917d2 100644 --- a/kernel/fs/fatfs.h +++ b/kernel/fs/fatfs.h @@ -29,4 +29,6 @@ int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct di int fatfs_create_file (struct vfs_volume* volume, const char* path); +int fatfs_create_dir (struct vfs_volume* volume, const char* path); + #endif // _KERNEL_FS_FATFS_H diff --git a/kernel/fs/tarfs.c b/kernel/fs/tarfs.c index 11dd794..263ea11 100644 --- a/kernel/fs/tarfs.c +++ b/kernel/fs/tarfs.c @@ -208,3 +208,8 @@ int tarfs_create_file (struct vfs_volume* volume, const char* path) { (void)volume, (void)path; return ST_OK; } + +int tarfs_create_dir (struct vfs_volume* volume, const char* path) { + (void)volume, (void)path; + return ST_OK; +} diff --git a/kernel/fs/tarfs.h b/kernel/fs/tarfs.h index 2c76042..0f04d49 100644 --- a/kernel/fs/tarfs.h +++ b/kernel/fs/tarfs.h @@ -51,4 +51,6 @@ int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct di int tarfs_create_file (struct vfs_volume* volume, const char* path); +int tarfs_create_dir (struct vfs_volume* volume, const char* path); + #endif // _KERNEL_FS_TARFS_H diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 7b144d1..4ffe620 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -61,6 +61,7 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device, volume->driver_ops.write_file = &tarfs_write_file; volume->driver_ops.read_dir_entry = &tarfs_read_dir_entry; volume->driver_ops.create_file = &tarfs_create_file; + volume->driver_ops.create_dir = &tarfs_create_dir; break; case VFS_FAT16: volume->driver_ops.mount = &fatfs_mount; @@ -70,6 +71,7 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device, volume->driver_ops.write_file = &fatfs_write_file; volume->driver_ops.read_dir_entry = &fatfs_read_dir_entry; volume->driver_ops.create_file = &fatfs_create_file; + volume->driver_ops.create_dir = &fatfs_create_dir; break; case VFS_FAT32: volume->driver_ops.mount = &fatfs_mount; @@ -79,6 +81,7 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device, volume->driver_ops.write_file = &fatfs_write_file; volume->driver_ops.read_dir_entry = &fatfs_read_dir_entry; volume->driver_ops.create_file = &fatfs_create_file; + volume->driver_ops.create_dir = &fatfs_create_dir; break; default: free (volume); @@ -279,6 +282,24 @@ int vfs_read_dir_entry (struct proc* proc, const char* volume_name, const char* return volume->driver_ops.read_dir_entry (volume, path, entry, entry_num); } +int vfs_create_dir (struct proc* proc, const char* volume_name, const char* path) { + 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.create_dir (volume, path); +} + void vfs_init (void) { memset (&volume_table, 0, sizeof (volume_table)); diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index b251f02..e0b7866 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -48,6 +48,8 @@ struct vfs_volume { size_t entry_num); int (*create_file) (struct vfs_volume* volume, const char* path); + + int (*create_dir) (struct vfs_volume* volume, const char* path); } driver_ops; struct device* back_device; void* udata @@ -79,6 +81,8 @@ int vfs_read_dir_entry (struct proc* proc, const char* volume, const char* path, int vfs_create_file (struct proc* proc, const char* volume_name, const char* path); +int vfs_create_dir (struct proc* proc, const char* volume_name, const char* path); + void vfs_init (void); void vfs_translate (size_t fs_block, size_t fs_block_count, size_t fs_block_size, diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 1ad73ce..7663419 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -593,6 +593,30 @@ DEFINE_SYSCALL (sys_kill) { return ST_OK; } +/* int create_dir (char* path) */ +DEFINE_SYSCALL (sys_create_dir) { + uintptr_t uvaddr_path = a1; + + 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); + + spin_lock (&proc->lock); + int ret = vfs_create_dir (proc, proc->cwv, path); + spin_unlock (&proc->lock); + + return SYSRESULT (ret); +} + static syscall_handler_func_t handler_table[] = { [SYS_QUIT] = &sys_quit, [SYS_TEST] = &sys_test, @@ -620,6 +644,7 @@ static syscall_handler_func_t handler_table[] = { [SYS_WRITE_FILE] = &sys_write_file, [SYS_WAIT_FOR_PID] = &sys_wait_for_pid, [SYS_KILL] = &sys_kill, + [SYS_CREATE_DIR] = &sys_create_dir, }; syscall_handler_func_t syscall_find_handler (int syscall_num) { diff --git a/libsystem/system.c b/libsystem/system.c index 4c816a6..74a041f 100644 --- a/libsystem/system.c +++ b/libsystem/system.c @@ -78,3 +78,5 @@ int write_file (const char* path, size_t off, uint8_t* buffer, size_t size, uint int wait_for_pid (int pid) { return (int)do_syscall (SYS_WAIT_FOR_PID, pid); } int kill (int pid) { return (int)do_syscall (SYS_KILL, pid); } + +int create_dir (const char* path) { return (int)do_syscall (SYS_CREATE_DIR, path); } diff --git a/libsystem/system.h b/libsystem/system.h index 4529d14..9e307b8 100644 --- a/libsystem/system.h +++ b/libsystem/system.h @@ -84,4 +84,7 @@ int wait_for_pid (int pid); /* Kill process */ int kill (int pid); +/* Create a directory */ +int create_dir (const char* path); + #endif // _LIBMSL_M_SYSTEM_H