diff --git a/BAN/BAN/String.cpp b/BAN/BAN/String.cpp index b1b4c95a..78031697 100644 --- a/BAN/BAN/String.cpp +++ b/BAN/BAN/String.cpp @@ -230,7 +230,7 @@ namespace BAN size_type new_cap = BAN::Math::max(size, m_capacity * 2); void* new_data = BAN::allocator(new_cap); if (new_data == nullptr) - return Error::from_string("String: Could not allocate memory"); + return Error::from_errno(ENOMEM); if (m_data) memcpy(new_data, m_data, m_size + 1); BAN::deallocator(m_data); diff --git a/BAN/include/BAN/Errors.h b/BAN/include/BAN/Errors.h index 177d78e4..b18cbb9e 100644 --- a/BAN/include/BAN/Errors.h +++ b/BAN/include/BAN/Errors.h @@ -3,6 +3,7 @@ #include #include +#include #include #if defined(__is_kernel) @@ -29,6 +30,14 @@ namespace BAN result.m_error_code = 0xFF; return result; } + static Error from_errno(int error) + { + Error result; + strncpy(result.m_message, strerror(error), sizeof(m_message)); + result.m_message[sizeof(result.m_message) - 1] = '\0'; + result.m_error_code = error; + return result; + } uint8_t get_error_code() const { return m_error_code; } const char* get_message() const { return m_message; } diff --git a/BAN/include/BAN/HashMap.h b/BAN/include/BAN/HashMap.h index 91c3dccb..b9e0a582 100644 --- a/BAN/include/BAN/HashMap.h +++ b/BAN/include/BAN/HashMap.h @@ -123,7 +123,7 @@ namespace BAN auto& bucket = get_bucket(key); auto result = bucket.emplace_back(key, forward(args)...); if (result.is_error()) - return Error::from_string("HashMap: Could not allocate memory"); + return Error::from_errno(ENOMEM); m_size++; return {}; } @@ -212,7 +212,7 @@ namespace BAN size_type new_bucket_count = BAN::Math::max(bucket_count, m_buckets.size() * 2); Vector> new_buckets; if (new_buckets.resize(new_bucket_count).is_error()) - return Error::from_string("HashMap: Could not allocate memory"); + return Error::from_errno(ENOMEM); // NOTE: We have to copy the old entries to the new entries and not move // since we might run out of memory half way through. @@ -222,7 +222,7 @@ namespace BAN { size_type bucket_index = HASH()(entry.key) % new_buckets.size(); if (new_buckets[bucket_index].push_back(entry).is_error()) - return Error::from_string("HashMap: Could not allocate memory"); + return Error::from_errno(ENOMEM); } } diff --git a/BAN/include/BAN/HashSet.h b/BAN/include/BAN/HashSet.h index 7656ba77..4e7e1aeb 100644 --- a/BAN/include/BAN/HashSet.h +++ b/BAN/include/BAN/HashSet.h @@ -197,7 +197,7 @@ namespace BAN size_type new_bucket_count = BAN::Math::max(bucket_count, m_buckets.size() * 2); Vector> new_buckets; if (new_buckets.resize(new_bucket_count).is_error()) - return Error::from_string("HashSet: Could not allocate memory"); + return Error::from_errno(ENOMEM); // NOTE: We have to copy the old keys to the new keys and not move // since we might run out of memory half way through. @@ -207,7 +207,7 @@ namespace BAN { size_type bucket_index = HASH()(key) % new_buckets.size(); if (new_buckets[bucket_index].push_back(key).is_error()) - return Error::from_string("HashSet: Could not allocate memory"); + return Error::from_errno(ENOMEM); } } diff --git a/BAN/include/BAN/LinkedList.h b/BAN/include/BAN/LinkedList.h index bac44b88..e270a9a7 100644 --- a/BAN/include/BAN/LinkedList.h +++ b/BAN/include/BAN/LinkedList.h @@ -288,7 +288,7 @@ namespace BAN { Node* node = (Node*)BAN::allocator(sizeof(Node)); if (node == nullptr) - return Error::from_string("LinkedList: Could not allocate memory"); + return Error::from_errno(ENOMEM); return node; } diff --git a/BAN/include/BAN/Memory.h b/BAN/include/BAN/Memory.h index 05854024..5a06ef3a 100644 --- a/BAN/include/BAN/Memory.h +++ b/BAN/include/BAN/Memory.h @@ -73,7 +73,7 @@ namespace BAN { uint32_t* count = new uint32_t(1); if (!count) - return Error::from_string("RefCounted: Could not allocate memory"); + return Error::from_errno(ENOMEM); return RefCounted((T*)data, count); } @@ -82,10 +82,10 @@ namespace BAN { uint32_t* count = new uint32_t(1); if (!count) - return Error::from_string("RefCounted: Could not allocate memory"); + return Error::from_errno(ENOMEM); T* data = new T(forward(args)...); if (!data) - return Error::from_string("RefCounted: Could not allocate memory"); + return Error::from_errno(ENOMEM); return RefCounted(data, count); } diff --git a/BAN/include/BAN/Queue.h b/BAN/include/BAN/Queue.h index 0ca50972..9ec8b14c 100644 --- a/BAN/include/BAN/Queue.h +++ b/BAN/include/BAN/Queue.h @@ -205,7 +205,7 @@ namespace BAN size_type new_cap = BAN::Math::max(size, m_capacity * 2); T* new_data = (T*)BAN::allocator(new_cap * sizeof(T)); if (new_data == nullptr) - return Error::from_string("Queue: Could not allocate memory"); + return Error::from_errno(ENOMEM); for (size_type i = 0; i < m_size; i++) { new (new_data + i) T(move(m_data[i])); diff --git a/BAN/include/BAN/Vector.h b/BAN/include/BAN/Vector.h index 3c1d01aa..69ca0877 100644 --- a/BAN/include/BAN/Vector.h +++ b/BAN/include/BAN/Vector.h @@ -400,7 +400,7 @@ namespace BAN size_type new_cap = BAN::Math::max(size, m_capacity * 2); T* new_data = (T*)BAN::allocator(new_cap * sizeof(T)); if (new_data == nullptr) - return Error::from_string("Vector: Could not allocate memory"); + return Error::from_errno(ENOMEM); for (size_type i = 0; i < m_size; i++) { new (new_data + i) T(move(m_data[i])); diff --git a/kernel/kernel/FS/Ext2.cpp b/kernel/kernel/FS/Ext2.cpp index 10d40b04..31d0935e 100644 --- a/kernel/kernel/FS/Ext2.cpp +++ b/kernel/kernel/FS/Ext2.cpp @@ -228,7 +228,7 @@ namespace Kernel BAN::ErrorOr> Ext2Inode::read_all() { if (ifdir()) - return BAN::Error::from_string("Inode is a directory"); + return BAN::Error::from_errno(EISDIR); BAN::Vector data_buffer; TRY(data_buffer.resize(m_inode.size)); @@ -256,7 +256,7 @@ namespace Kernel BAN::ErrorOr> Ext2Inode::directory_find(BAN::StringView file_name) { if (!ifdir()) - return BAN::Error::from_string("Inode is not a directory"); + return BAN::Error::from_errno(ENOTDIR); BAN::RefCounted result; BAN::Function(const BAN::Vector&)> function( @@ -272,7 +272,7 @@ namespace Kernel { Ext2Inode* inode = new Ext2Inode(m_fs, TRY(m_fs->read_inode(entry->inode)), entry_name); if (inode == nullptr) - return BAN::Error::from_string("Could not allocate Ext2Inode"); + return BAN::Error::from_errno(ENOMEM); result = TRY(BAN::RefCounted::adopt(inode)); return false; } @@ -285,13 +285,13 @@ namespace Kernel TRY(for_each_block(function)); if (result) return result; - return BAN::Error::from_string("Could not find the asked inode"); + return BAN::Error::from_errno(ENOENT); } BAN::ErrorOr>> Ext2Inode::directory_inodes() { if (!ifdir()) - return BAN::Error::from_string("Inode is not a directory"); + return BAN::Error::from_errno(ENOTDIR); BAN::Vector> inodes; BAN::Function(const BAN::Vector&)> function( @@ -309,7 +309,7 @@ namespace Kernel Ext2Inode* inode = new Ext2Inode(m_fs, BAN::move(current_inode), entry_name); if (inode == nullptr) - return BAN::Error::from_string("Could not allocate memory for Ext2Inode"); + return BAN::Error::from_errno(ENOMEM); TRY(inodes.push_back(TRY(BAN::RefCounted::adopt(inode)))); } entry_addr += entry->rec_len; @@ -327,7 +327,7 @@ namespace Kernel { Ext2FS* ext2fs = new Ext2FS(partition); if (ext2fs == nullptr) - return BAN::Error::from_string("Could not allocate Ext2FS"); + return BAN::Error::from_errno(ENOMEM); TRY(ext2fs->initialize_superblock()); TRY(ext2fs->initialize_block_group_descriptors()); TRY(ext2fs->initialize_root_inode()); @@ -343,7 +343,7 @@ namespace Kernel { uint8_t* superblock_buffer = (uint8_t*)kmalloc(1024); if (superblock_buffer == nullptr) - return BAN::Error::from_string("Could not allocate memory for superblocks"); + BAN::Error::from_errno(ENOMEM); BAN::ScopeGuard _([superblock_buffer] { kfree(superblock_buffer); }); uint32_t lba = 1024 / sector_size; @@ -399,7 +399,7 @@ namespace Kernel uint8_t* block_group_descriptor_table_buffer = (uint8_t*)kmalloc(block_group_descriptor_table_sector_count * sector_size); if (block_group_descriptor_table_buffer == nullptr) - return BAN::Error::from_string("Could not allocate memory for block group descriptor table"); + return BAN::Error::from_errno(ENOMEM); BAN::ScopeGuard _([block_group_descriptor_table_buffer] { kfree(block_group_descriptor_table_buffer); }); TRY(m_partition.read_sectors( @@ -428,12 +428,11 @@ namespace Kernel BAN::ErrorOr Ext2FS::initialize_root_inode() { - Ext2Inode* root_inode = new Ext2Inode(this, TRY(read_inode(Ext2::Enum::ROOT_INO)), ""); if (root_inode == nullptr) - return BAN::Error::from_string("Could not allocate Ext2Inode"); + return BAN::Error::from_errno(ENOMEM); m_root_inode = TRY(BAN::RefCounted::adopt(root_inode)); - + #if EXT2_DEBUG_PRINT dprintln("root inode:"); dprintln(" created {}", ext2_root_inode().ctime); diff --git a/kernel/kernel/FS/VirtualFileSystem.cpp b/kernel/kernel/FS/VirtualFileSystem.cpp index 47b4c31a..0b38222e 100644 --- a/kernel/kernel/FS/VirtualFileSystem.cpp +++ b/kernel/kernel/FS/VirtualFileSystem.cpp @@ -15,7 +15,7 @@ namespace Kernel ASSERT(s_instance == nullptr); s_instance = new VirtualFileSystem(); if (s_instance == nullptr) - return BAN::Error::from_string("Could not allocate the Virtual File System"); + return BAN::Error::from_errno(ENOMEM); return s_instance->initialize_impl(); } diff --git a/kernel/kernel/Shell.cpp b/kernel/kernel/Shell.cpp index 1c847cc4..53f5ff4f 100644 --- a/kernel/kernel/Shell.cpp +++ b/kernel/kernel/Shell.cpp @@ -271,9 +271,6 @@ argument_done: return TTY_PRINTLN("{}", directory_or_error.error()); auto directory = directory_or_error.release_value(); - if (!directory->ifdir()) - return TTY_PRINTLN("Given path does not point to a directory"); - auto inodes_or_error = directory->directory_inodes(); if (inodes_or_error.is_error()) return TTY_PRINTLN("{}", inodes_or_error.error()); diff --git a/kernel/kernel/Storage/ATAController.cpp b/kernel/kernel/Storage/ATAController.cpp index 8dd5fadf..fd199f29 100644 --- a/kernel/kernel/Storage/ATAController.cpp +++ b/kernel/kernel/Storage/ATAController.cpp @@ -54,7 +54,7 @@ namespace Kernel { ATAController* controller = new ATAController(device); if (controller == nullptr) - return BAN::Error::from_string("Could not allocate memory for ATAController"); + return BAN::Error::from_errno(ENOMEM); TRY(controller->initialize()); return controller; } @@ -256,7 +256,7 @@ namespace Kernel if (status & ATA_STATUS_ERR) return error(); if (status & ATA_STATUS_DF) - return BAN::Error::from_string("Device fault"); + return BAN::Error::from_errno(EIO); status = read(ATA_PORT_STATUS); } diff --git a/libc/Makefile b/libc/Makefile index 45fbf117..d8d5b2e8 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -41,9 +41,10 @@ string/memcpy.o \ string/memmove.o \ string/memset.o \ string/strcmp.o \ -string/strncmp.o \ string/strcpy.o \ +string/strerror.o \ string/strlen.o \ +string/strncmp.o \ string/strncpy.o \ string/strstr.o \ diff --git a/libc/include/errno.h b/libc/include/errno.h new file mode 100644 index 00000000..34052c3f --- /dev/null +++ b/libc/include/errno.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +#define ENOMEM 1 +#define EINVAL 2 +#define ENOTDIR 3 +#define EISDIR 4 +#define ENOENT 5 +#define EIO 6 + +__BEGIN_DECLS + +extern int errno; + +__END_DECLS \ No newline at end of file diff --git a/libc/include/string.h b/libc/include/string.h index 491a36a3..6f5844ee 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -19,4 +19,6 @@ char* strncpy(char* __restrict, const char* __restrict, size_t); char* strstr(const char*, const char*); +char* strerror(int); + __END_DECLS \ No newline at end of file diff --git a/libc/string/strerror.cpp b/libc/string/strerror.cpp new file mode 100644 index 00000000..4a554a8b --- /dev/null +++ b/libc/string/strerror.cpp @@ -0,0 +1,32 @@ +#include +#include + +int errno = 0; + +char* strerror(int error) +{ + switch (error) + { + case ENOMEM: + return "Cannot allocate memory"; + case EINVAL: + return "Invalid argument"; + case EISDIR: + return "Is a directory"; + case ENOTDIR: + return "Not a directory"; + case ENOENT: + return "No such file or directory"; + case EIO: + return "Input/output error"; + default: + break; + } + + // FIXME: sprintf + //static char buffer[26]; + //sprintf(buffer, "Unknown error %d", error); + //return buffer; + errno = EINVAL; + return "Unknown error"; +} \ No newline at end of file