diff --git a/kernel/include/errno.h b/kernel/include/errno.h index 29e65eae..e38e0d11 100644 --- a/kernel/include/errno.h +++ b/kernel/include/errno.h @@ -6,7 +6,11 @@ #define EBADF 9 #define ENOMEM 12 #define EFAULT 14 +#define EEXIST 17 +#define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define EMFILE 24 -#define ENOSYS 38 \ No newline at end of file +#define ENOSPC 28 +#define ENOSYS 38 +#define ENOTSUP 95 \ No newline at end of file diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h index e92a795f..adc6c060 100644 --- a/kernel/include/sys/Syscall.h +++ b/kernel/include/sys/Syscall.h @@ -18,6 +18,7 @@ #define SYS_fcntl 13 #define SYS_mprotect 14 #define SYS_clock 15 +#define SYS_mkdir 17 // 16 is reserved for fork(), which is WIP in a pull request namespace Syscall { @@ -41,4 +42,5 @@ void sys_seek(Context* context, int fd, long offset, int whence); void sys_exec(Context* context, const char* pathname); void sys_fcntl(Context* context, int fd, int command, uintptr_t arg); void sys_mprotect(Context* context, void* address, size_t size, int prot); -void sys_clock(Context* context); \ No newline at end of file +void sys_clock(Context* context); +void sys_mkdir(Context* context, const char* filename); \ No newline at end of file diff --git a/kernel/src/fs/VFS.cpp b/kernel/src/fs/VFS.cpp index df8566a7..f2c175c6 100644 --- a/kernel/src/fs/VFS.cpp +++ b/kernel/src/fs/VFS.cpp @@ -132,12 +132,27 @@ int VFS::mkdir(const char* path, const char* name) if (!node) { kwarnln("Attempting to mkdir in %s, which does not exist", path); - return -1; + return -ENOENT; + } + if (node->type != VFS_DIRECTORY) + { + kwarnln("Attempting to mkdir in %s, which is not a directory!!", path); + return -ENOTDIR; } if (!node->mkdir_func) { kwarnln("Chosen node does not support mkdir()"); - return -1; + return -ENOTSUP; + } + if (!node->find_func) + { + kwarnln("Chosen node does not support finddir()"); + return -ENOTSUP; + } + if (node->find_func(node, name) != nullptr) + { + kwarnln("Already exists"); + return -EEXIST; } return node->mkdir_func(node, name); } diff --git a/kernel/src/init/InitRD.cpp b/kernel/src/init/InitRD.cpp index 72553348..45d58892 100644 --- a/kernel/src/init/InitRD.cpp +++ b/kernel/src/init/InitRD.cpp @@ -2,6 +2,7 @@ #include "init/InitRD.h" #include "bootboot.h" +#include "errno.h" #include "fs/VFS.h" #include "io/Serial.h" #include "log/Log.h" @@ -190,23 +191,23 @@ int initrd_mkdir(VFS::Node* node, const char* name) // FIXME: Return proper erro if (total_dirs >= 32) { kwarnln("mkdir() failed: too many directories"); - return -1; + return -ENOSPC; } if (node->inode > total_dirs) { kwarnln("mkdir() failed: invalid node"); - return -1; + return -EINVAL; } if (!(node->type & VFS_DIRECTORY)) { kwarnln("mkdir() failed: not a directory"); - return -1; + return -ENOTDIR; } InitRD::Directory& parent = dirs[node->inode]; if (parent.entries == INITRD_MAX_FILES_IN_DIR) { - kwarnln("mkdir() failed: parent is null"); - return -1; + kwarnln("mkdir() failed: parent is full"); + return -ENOSPC; } uint64_t inode = total_dirs; VFS::Node& new_node = nodes[total_nodes++]; diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp index 243756ed..eb4f66e8 100644 --- a/kernel/src/sys/Syscall.cpp +++ b/kernel/src/sys/Syscall.cpp @@ -27,6 +27,7 @@ void Syscall::entry(Context* context) case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break; case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break; case SYS_clock: sys_clock(context); break; + case SYS_mkdir: sys_mkdir(context, (const char*)context->rdi); break; default: context->rax = -ENOSYS; break; } VMM::exit_syscall_context(); diff --git a/kernel/src/sys/stdio.cpp b/kernel/src/sys/stdio.cpp index ac31b1b4..a32e8d55 100644 --- a/kernel/src/sys/stdio.cpp +++ b/kernel/src/sys/stdio.cpp @@ -217,4 +217,20 @@ void sys_close(Context* context, int fd) current_task->files[fd].close(); context->rax = 0; return; +} + +void sys_mkdir(Context* context, const char* filename) +{ + char* kfilename = Syscall::strdup_from_user(filename); + if (!kfilename) + { + context->rax = -EFAULT; + return; + } + + int rc = VFS::mkdir(kfilename); + + kfree(kfilename); + + context->rax = rc; } \ No newline at end of file diff --git a/libs/libc/include/errno.h b/libs/libc/include/errno.h index 25ae3a94..d0f0a9fa 100644 --- a/libs/libc/include/errno.h +++ b/libs/libc/include/errno.h @@ -4,16 +4,20 @@ /* The last error encountered during a call to a library or system function. */ extern int errno; -#define EPERM 1 // Operation not permitted -#define ENOENT 2 // No such file or directory -#define ENOEXEC 8 // Exec format error -#define EBADF 9 // Bad file descriptor -#define ENOMEM 12 // Cannot allocate memory -#define EFAULT 14 // Bad address -#define EISDIR 21 // Is a directory -#define EINVAL 22 // Invalid argument -#define EMFILE 24 // Too many open files -#define EPIPE 32 // Broken pipe. Not implemented. -#define ENOSYS 38 // Function not implemented +#define EPERM 1 // Operation not permitted +#define ENOENT 2 // No such file or directory +#define ENOEXEC 8 // Exec format error +#define EBADF 9 // Bad file descriptor +#define ENOMEM 12 // Cannot allocate memory +#define EFAULT 14 // Bad address +#define EEXIST 17 // File exists +#define ENOTDIR 10 // Not a directory +#define EISDIR 21 // Is a directory +#define EINVAL 22 // Invalid argument +#define EMFILE 24 // Too many open files +#define ENOSPC 28 // No space left on device +#define EPIPE 32 // Broken pipe. Not implemented. +#define ENOSYS 38 // Function not implemented +#define ENOTSUP 95 // Operation not supported. #endif \ No newline at end of file