From 292433dc39185ce6e58cf06fee3dcf3a8322add7 Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 12 Mar 2023 11:37:41 +0100 Subject: [PATCH] kernel+libc: Add the write() system call, and fwrite() --- kernel/src/sys/file.cpp | 23 +++++++++++++++++++++++ libc/include/stdio.h | 3 ++- libc/include/unistd.h | 3 +++ libc/src/stdio.cpp | 9 +++++++++ libc/src/unistd.cpp | 6 ++++++ libluna/include/luna/Syscall.h | 2 +- 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/kernel/src/sys/file.cpp b/kernel/src/sys/file.cpp index a9ce6b72..8785a2fc 100644 --- a/kernel/src/sys/file.cpp +++ b/kernel/src/sys/file.cpp @@ -26,3 +26,26 @@ Result sys_read(Registers*, SyscallArgs args) return nread; } + +Result sys_write(Registers*, SyscallArgs args) +{ + int fd = (int)args[0]; + const u8* buf = (const u8*)args[1]; + usize size = (usize)args[2]; + + if (!MemoryManager::validate_user_read(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 nwritten = TRY(descriptor->inode->write(buf, descriptor->offset, size)); + + descriptor->offset += nwritten; + + return nwritten; +} diff --git a/libc/include/stdio.h b/libc/include/stdio.h index a37fac48..545faaf5 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -35,7 +35,8 @@ extern "C" /* Read arbitrarily sized items from a stream. */ size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream); - size_t fwrite(const void*, size_t, size_t, FILE*); + /* Write arbitrarily sized items to a stream. */ + size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream); int fseek(FILE*, long, int); long ftell(FILE*); diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 5ce1e3ba..bb6a0a3e 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -38,6 +38,9 @@ extern "C" /* Read bytes from a file descriptor. */ ssize_t read(int fd, void* buf, size_t size); + /* Write bytes to a file descriptor. */ + ssize_t write(int fd, const void* buf, size_t size); + #ifdef __cplusplus } #endif diff --git a/libc/src/stdio.cpp b/libc/src/stdio.cpp index 5305abbd..07951eea 100644 --- a/libc/src/stdio.cpp +++ b/libc/src/stdio.cpp @@ -66,6 +66,15 @@ extern "C" return (size_t)nread / size; } + size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream) + { + if (size * nmemb == 0) return 0; + + ssize_t nwrite = write(stream->_fd, buf, size * nmemb); + + return (size_t)nwrite / size; + } + int ferror(FILE* stream) { return stream->_err; diff --git a/libc/src/unistd.cpp b/libc/src/unistd.cpp index 220d429b..ebbd189e 100644 --- a/libc/src/unistd.cpp +++ b/libc/src/unistd.cpp @@ -54,4 +54,10 @@ extern "C" long rc = syscall(SYS_read, fd, buf, size); __errno_return(rc, ssize_t); } + + ssize_t write(int fd, const void* buf, size_t size) + { + long rc = syscall(SYS_write, fd, buf, size); + __errno_return(rc, ssize_t); + } } diff --git a/libluna/include/luna/Syscall.h b/libluna/include/luna/Syscall.h index f6516ecc..64928e9a 100644 --- a/libluna/include/luna/Syscall.h +++ b/libluna/include/luna/Syscall.h @@ -2,7 +2,7 @@ #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(read) _e(getpid) + _e(close) _e(read) _e(getpid) _e(write) enum Syscalls {