diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 31e3e282d9..2144045289 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -112,6 +112,7 @@ namespace Kernel BAN::ErrorOr sys_symlinkat(const char* path1, int fd, const char* path2); BAN::ErrorOr sys_pread(int fd, void* buffer, size_t count, off_t offset); + BAN::ErrorOr sys_pwrite(int fd, const void* buffer, size_t count, off_t offset); BAN::ErrorOr sys_fchmodat(int fd, const char* path, mode_t mode, int flag); BAN::ErrorOr sys_fchownat(int fd, const char* path, uid_t uid, gid_t gid, int flag); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index fd2b735940..c6f4737e56 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -1192,17 +1192,23 @@ namespace Kernel BAN::ErrorOr Process::sys_pread(int fd, void* buffer, size_t count, off_t offset) { - LockGuard _(m_process_lock); - if (count == 0) - { - TRY(m_open_file_descriptors.inode_of(fd)); - return 0; - } - TRY(validate_pointer_access(buffer, count, true)); auto inode = TRY(m_open_file_descriptors.inode_of(fd)); - return TRY(inode->read(offset, { (uint8_t*)buffer, count })); + + auto* buffer_region = TRY(validate_and_pin_pointer_access(buffer, count, true)); + BAN::ScopeGuard _([buffer_region]{ if (buffer_region) buffer_region->unpin(); }); + + return TRY(inode->read(offset, { reinterpret_cast(buffer), count })); } + BAN::ErrorOr Process::sys_pwrite(int fd, const void* buffer, size_t count, off_t offset) + { + auto inode = TRY(m_open_file_descriptors.inode_of(fd)); + + auto* buffer_region = TRY(validate_and_pin_pointer_access(buffer, count, false)); + BAN::ScopeGuard _([buffer_region]{ if (buffer_region) buffer_region->unpin(); }); + + return TRY(inode->write(offset, { reinterpret_cast(buffer), count })); } + BAN::ErrorOr Process::sys_fchmodat(int fd, const char* path, mode_t mode, int flag) { if (mode & S_IFMASK) diff --git a/userspace/libraries/LibC/include/sys/syscall.h b/userspace/libraries/LibC/include/sys/syscall.h index 21688f16e8..27fa9a8296 100644 --- a/userspace/libraries/LibC/include/sys/syscall.h +++ b/userspace/libraries/LibC/include/sys/syscall.h @@ -60,6 +60,7 @@ __BEGIN_DECLS O(SYS_READLINKAT, readlinkat) \ O(SYS_MSYNC, msync) \ O(SYS_PREAD, pread) \ + O(SYS_PWRITE, pwrite) \ O(SYS_FCHOWNAT, fchownat) \ O(SYS_LOAD_KEYMAP, load_keymap) \ O(SYS_SOCKET, socket) \ diff --git a/userspace/libraries/LibC/unistd.cpp b/userspace/libraries/LibC/unistd.cpp index 22a02895c3..4b98113cc0 100644 --- a/userspace/libraries/LibC/unistd.cpp +++ b/userspace/libraries/LibC/unistd.cpp @@ -127,6 +127,11 @@ ssize_t pread(int fildes, void* buf, size_t nbyte, off_t offset) return syscall(SYS_PREAD, fildes, buf, nbyte, offset); } +ssize_t pwrite(int fildes, const void* buf, size_t nbyte, off_t offset) +{ + return syscall(SYS_PWRITE, fildes, buf, nbyte, offset); +} + off_t lseek(int fildes, off_t offset, int whence) { return syscall(SYS_SEEK, fildes, offset, whence);