diff --git a/Core/Memory/MemoryManager.cpp b/Core/Memory/MemoryManager.cpp index 6b1edc9..b76eb6f 100644 --- a/Core/Memory/MemoryManager.cpp +++ b/Core/Memory/MemoryManager.cpp @@ -46,10 +46,45 @@ namespace Memory return Size; } + SeekFSFunction(MEM_Seek) + { + long NewOffset; + + if (Whence == SEEK_SET) + { + if (Offset > node->Length) + return -1; + node->Offset = Offset; + NewOffset = node->Offset; + } + else if (Whence == SEEK_CUR) + { + NewOffset = node->Offset + Offset; + if (NewOffset > node->Length || NewOffset < 0) + return -1; + node->Offset = NewOffset; + } + else if (Whence == SEEK_END) + { + NewOffset = node->Length + Offset; + if (NewOffset < 0) + return -1; + node->Offset = NewOffset; + } + else + { + error("Invalid whence!"); + return -1; + } + + return NewOffset; + } + VirtualFileSystem::FileSystemOperations mem_op = { .Name = "mem", .Read = MEM_Read, .Write = MEM_Write, + .Seek = MEM_Seek, }; uint64_t MemMgr::GetAllocatedMemorySize() diff --git a/FileSystem/FS/ustar.cpp b/FileSystem/FS/ustar.cpp index 6b89fb6..6adb5f2 100644 --- a/FileSystem/FS/ustar.cpp +++ b/FileSystem/FS/ustar.cpp @@ -36,9 +36,44 @@ namespace VirtualFileSystem return Size; } + SeekFSFunction(USTAR_Seek) + { + long NewOffset; + + if (Whence == SEEK_SET) + { + if (Offset > node->Length) + return -1; + node->Offset = Offset; + NewOffset = node->Offset; + } + else if (Whence == SEEK_CUR) + { + NewOffset = node->Offset + Offset; + if (NewOffset > node->Length || NewOffset < 0) + return -1; + node->Offset = NewOffset; + } + else if (Whence == SEEK_END) + { + NewOffset = node->Length + Offset; + if (NewOffset < 0) + return -1; + node->Offset = NewOffset; + } + else + { + error("Invalid whence!"); + return -1; + } + + return NewOffset; + } + FileSystemOperations ustar_op = { .Name = "ustar", .Read = USTAR_Read, + .Seek = USTAR_Seek, }; USTAR::USTAR(uintptr_t Address, Virtual *vfs_ctx) diff --git a/SystemCalls/Native.cpp b/SystemCalls/Native.cpp index 8d9c8c2..03fa5e6 100644 --- a/SystemCalls/Native.cpp +++ b/SystemCalls/Native.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -301,10 +302,19 @@ static uint64_t sys_file_write(SyscallsFrame *Frame, void *KernelPrivate, uint64 UNUSED(Frame); } -static int sys_file_seek(SyscallsFrame *Frame) +static uint64_t sys_file_seek(SyscallsFrame *Frame, void *KernelPrivate, uint64_t Offset, int Whence) { - fixme("sys_file_seek: %#lx", Frame); - return SYSCALL_NOT_IMPLEMENTED; + if (KernelPrivate == nullptr) + return 0; + + debug("(KernelPrivate: %#lx, Offset: %#lx, Whence: %#lx)", KernelPrivate, Offset, Whence); + VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate; + + if (KPObj->node->Operator->Seek == nullptr) + return SYSCALL_INTERNAL_ERROR; + + return KPObj->node->Operator->Seek(KPObj->node, Offset, Whence); + UNUSED(Frame); } static int sys_file_status(SyscallsFrame *Frame) diff --git a/include/filesystem.hpp b/include/filesystem.hpp index 8b135ff..188dece 100644 --- a/include/filesystem.hpp +++ b/include/filesystem.hpp @@ -26,6 +26,10 @@ namespace VirtualFileSystem { #define FILENAME_LENGTH 256 +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + struct Node; typedef size_t (*OperationMount)(const char *, unsigned long, const void *); @@ -37,6 +41,7 @@ namespace VirtualFileSystem typedef size_t (*OperationSync)(void); typedef void (*OperationCreate)(Node *node, char *Name, uint16_t NameLength); typedef void (*OperationMkdir)(Node *node, char *Name, uint16_t NameLength); + typedef size_t (*OperationSeek)(Node *node, size_t Offset, uint8_t Whence); #define MountFSFunction(name) size_t name(const char *unknown0, unsigned long unknown1, const uint8_t *unknown2) #define UMountFSFunction(name) size_t name(int unknown0) @@ -48,6 +53,7 @@ namespace VirtualFileSystem #define SyncFSFunction(name) size_t name(void) #define CreateFSFunction(name) void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength) #define MkdirFSFunction(name) void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength) +#define SeekFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Offset, uint8_t Whence) enum FileStatus { @@ -101,6 +107,7 @@ namespace VirtualFileSystem OperationClose Close = nullptr; OperationCreate Create = nullptr; OperationMkdir MakeDirectory = nullptr; + OperationSeek Seek = nullptr; }; struct Node @@ -113,6 +120,7 @@ namespace VirtualFileSystem uint64_t UserIdentifier = 0, GroupIdentifier = 0; uintptr_t Address = 0; size_t Length = 0; + uint64_t Offset = 0; Node *Parent = nullptr; FileSystemOperations *Operator = nullptr; /* For root node: diff --git a/syscalls.h b/syscalls.h index a1f6ca9..e6687fa 100644 --- a/syscalls.h +++ b/syscalls.h @@ -109,7 +109,7 @@ enum NativeSyscalls _FileWrite, /** @brief Seek in a file - * @fn + * @fn uint64_t FileSeek(void *KernelPrivate, uint64_t Offset, int Whence) * This syscall is used to change the current offset in a file. */ _FileSeek,