From 8fa72f3cf067bf570803ef49c858548b3f04067f Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 11 Mar 2023 18:02:50 +0100 Subject: [PATCH] kernel+libc: Implement read() --- apps/app.c | 6 ++++++ kernel/CMakeLists.txt | 1 + kernel/src/sys/file.cpp | 28 ++++++++++++++++++++++++++++ kernel/src/sys/open.cpp | 9 +++++---- libc/include/sys/types.h | 1 + libc/include/unistd.h | 3 +++ libc/src/unistd.cpp | 6 ++++++ libluna/include/luna/Syscall.h | 3 ++- 8 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 kernel/src/sys/file.cpp diff --git a/apps/app.c b/apps/app.c index 44449860..eeaaadfc 100644 --- a/apps/app.c +++ b/apps/app.c @@ -21,6 +21,12 @@ int main() return 1; } + char buffer[512]; + ssize_t nread = read(fd, buffer, sizeof(buffer)); + buffer[nread] = 0; + + printf("/etc/motd says: %s", buffer); + close(fd); time_t now = time(NULL); diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 719384d4..6c53ecb3 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -27,6 +27,7 @@ set(SOURCES src/sys/allocate_memory.cpp src/sys/usleep.cpp src/sys/open.cpp + src/sys/file.cpp src/fs/VFS.cpp src/fs/tmpfs/FileSystem.cpp src/InitRD.cpp diff --git a/kernel/src/sys/file.cpp b/kernel/src/sys/file.cpp new file mode 100644 index 00000000..a9ce6b72 --- /dev/null +++ b/kernel/src/sys/file.cpp @@ -0,0 +1,28 @@ +#include "Log.h" +#include "fs/VFS.h" +#include "memory/MemoryManager.h" +#include "sys/Syscall.h" +#include "thread/Scheduler.h" + +Result sys_read(Registers*, SyscallArgs args) +{ + int fd = (int)args[0]; + u8* buf = (u8*)args[1]; + usize size = (usize)args[2]; + + if (!MemoryManager::validate_user_write(buf, size)) return err(EFAULT); + + if (fd < 0 || fd >= FD_MAX) return err(EBADF); + + Thread* current = Scheduler::current(); + + Option& descriptor = current->fd_table->fds[fd]; + + if (!descriptor.has_value()) return err(EBADF); + + usize nread = TRY(descriptor->inode->read(buf, descriptor->offset, size)); + + descriptor->offset += nread; + + return nread; +} diff --git a/kernel/src/sys/open.cpp b/kernel/src/sys/open.cpp index 5468ef6c..d2decfde 100644 --- a/kernel/src/sys/open.cpp +++ b/kernel/src/sys/open.cpp @@ -34,12 +34,13 @@ Result sys_close(Registers*, SyscallArgs args) Thread* current = Scheduler::current(); - if (!current->fd_table->fds[fd].has_value()) return err(EBADF); + Option& descriptor = current->fd_table->fds[fd]; - kinfoln("close: closing file descriptor %d (was referencing inode %zu)", fd, - current->fd_table->fds[fd]->inode->inode_number()); + if (!descriptor.has_value()) return err(EBADF); - current->fd_table->fds[fd] = {}; + kinfoln("close: closing file descriptor %d (was referencing inode %zu)", fd, descriptor->inode->inode_number()); + + descriptor = {}; return 0; } diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h index c4adbd49..e6917712 100644 --- a/libc/include/sys/types.h +++ b/libc/include/sys/types.h @@ -9,6 +9,7 @@ #include typedef int pid_t; +typedef __i64_t ssize_t; typedef __i64_t time_t; typedef __u16_t mode_t; typedef __u64_t useconds_t; diff --git a/libc/include/unistd.h b/libc/include/unistd.h index f7782ff1..6bef9cf3 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -33,6 +33,9 @@ extern "C" /* Closes a file descriptor. */ int close(int fd); + /* Reads bytes from a file descriptor. */ + ssize_t read(int fd, void* buf, size_t size); + #ifdef __cplusplus } #endif diff --git a/libc/src/unistd.cpp b/libc/src/unistd.cpp index 4e459bd1..02374238 100644 --- a/libc/src/unistd.cpp +++ b/libc/src/unistd.cpp @@ -43,4 +43,10 @@ extern "C" long rc = syscall(SYS_close, fd); __errno_return(rc, int); } + + ssize_t read(int fd, void* buf, size_t size) + { + long rc = syscall(SYS_read, fd, buf, size); + __errno_return(rc, ssize_t); + } } diff --git a/libluna/include/luna/Syscall.h b/libluna/include/luna/Syscall.h index 2e4afc2a..1797b548 100644 --- a/libluna/include/luna/Syscall.h +++ b/libluna/include/luna/Syscall.h @@ -1,7 +1,8 @@ #pragma once #define enumerate_syscalls(_e) \ - _e(exit) _e(console_write) _e(clock_gettime) _e(allocate_memory) _e(deallocate_memory) _e(usleep) _e(open) _e(close) + _e(exit) _e(console_write) _e(clock_gettime) _e(allocate_memory) _e(deallocate_memory) _e(usleep) _e(open) \ + _e(close) _e(read) enum Syscalls {