diff --git a/Kernel/Process.h b/Kernel/Process.h index 83bade854a..13140665bd 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -212,151 +212,151 @@ public: void stop_tracing(); void tracer_trap(Thread&, const RegisterState&); - int sys$yield(); - int sys$sync(); - int sys$beep(); - int sys$get_process_name(Userspace buffer, size_t buffer_size); - int sys$set_process_name(Userspace user_name, size_t user_name_length); - int sys$watch_file(Userspace path, size_t path_length); - int sys$dbgputch(u8); - int sys$dbgputstr(Userspace, int length); - int sys$dump_backtrace(); - pid_t sys$gettid(); - int sys$donate(pid_t tid); - int sys$ftruncate(int fd, off_t); - pid_t sys$setsid(); - pid_t sys$getsid(pid_t); - int sys$setpgid(pid_t pid, pid_t pgid); - pid_t sys$getpgrp(); - pid_t sys$getpgid(pid_t); - uid_t sys$getuid(); - gid_t sys$getgid(); - uid_t sys$geteuid(); - gid_t sys$getegid(); - pid_t sys$getpid(); - pid_t sys$getppid(); - int sys$getresuid(Userspace, Userspace, Userspace); - int sys$getresgid(Userspace, Userspace, Userspace); - mode_t sys$umask(mode_t); - int sys$open(Userspace); - int sys$close(int fd); - ssize_t sys$read(int fd, Userspace, ssize_t); - ssize_t sys$readv(int fd, Userspace iov, int iov_count); - ssize_t sys$write(int fd, const u8*, ssize_t); - ssize_t sys$writev(int fd, Userspace iov, int iov_count); - int sys$fstat(int fd, Userspace); - int sys$stat(Userspace); - int sys$lseek(int fd, off_t, int whence); - int sys$kill(pid_t pid_or_pgid, int sig); + KResultOr sys$yield(); + KResultOr sys$sync(); + KResultOr sys$beep(); + KResultOr sys$get_process_name(Userspace buffer, size_t buffer_size); + KResultOr sys$set_process_name(Userspace user_name, size_t user_name_length); + KResultOr sys$watch_file(Userspace path, size_t path_length); + KResultOr sys$dbgputch(u8); + KResultOr sys$dbgputstr(Userspace, int length); + KResultOr sys$dump_backtrace(); + KResultOr sys$gettid(); + KResultOr sys$donate(pid_t tid); + KResultOr sys$ftruncate(int fd, off_t); + KResultOr sys$setsid(); + KResultOr sys$getsid(pid_t); + KResultOr sys$setpgid(pid_t pid, pid_t pgid); + KResultOr sys$getpgrp(); + KResultOr sys$getpgid(pid_t); + KResultOr sys$getuid(); + KResultOr sys$getgid(); + KResultOr sys$geteuid(); + KResultOr sys$getegid(); + KResultOr sys$getpid(); + KResultOr sys$getppid(); + KResultOr sys$getresuid(Userspace, Userspace, Userspace); + KResultOr sys$getresgid(Userspace, Userspace, Userspace); + KResultOr sys$umask(mode_t); + KResultOr sys$open(Userspace); + KResultOr sys$close(int fd); + KResultOr sys$read(int fd, Userspace, ssize_t); + KResultOr sys$readv(int fd, Userspace iov, int iov_count); + KResultOr sys$write(int fd, const u8*, ssize_t); + KResultOr sys$writev(int fd, Userspace iov, int iov_count); + KResultOr sys$fstat(int fd, Userspace); + KResultOr sys$stat(Userspace); + KResultOr sys$lseek(int fd, off_t, int whence); + KResultOr sys$kill(pid_t pid_or_pgid, int sig); [[noreturn]] void sys$exit(int status); - int sys$sigreturn(RegisterState& registers); - pid_t sys$waitid(Userspace); - FlatPtr sys$mmap(Userspace); - FlatPtr sys$mremap(Userspace); - int sys$munmap(void*, size_t size); - int sys$set_mmap_name(Userspace); - int sys$mprotect(void*, size_t, int prot); - int sys$madvise(void*, size_t, int advice); - int sys$msyscall(void*); - int sys$purge(int mode); - int sys$select(const Syscall::SC_select_params*); - int sys$poll(Userspace); - ssize_t sys$get_dir_entries(int fd, void*, ssize_t); - int sys$getcwd(Userspace, size_t); - int sys$chdir(Userspace, size_t); - int sys$fchdir(int fd); - int sys$adjtime(Userspace, Userspace); - int sys$gettimeofday(Userspace); - int sys$clock_gettime(clockid_t, Userspace); - int sys$clock_settime(clockid_t, Userspace); - int sys$clock_nanosleep(Userspace); - int sys$gethostname(Userspace, ssize_t); - int sys$sethostname(Userspace, ssize_t); - int sys$uname(Userspace); - int sys$readlink(Userspace); - int sys$ttyname(int fd, Userspace, size_t); - int sys$ptsname(int fd, Userspace, size_t); - pid_t sys$fork(RegisterState&); - int sys$execve(Userspace); - int sys$dup2(int old_fd, int new_fd); - int sys$sigaction(int signum, const sigaction* act, sigaction* old_act); - int sys$sigprocmask(int how, Userspace set, Userspace old_set); - int sys$sigpending(Userspace); - int sys$getgroups(ssize_t, Userspace); - int sys$setgroups(ssize_t, Userspace); - int sys$pipe(int pipefd[2], int flags); - int sys$killpg(pid_t pgrp, int sig); - int sys$seteuid(uid_t); - int sys$setegid(gid_t); - int sys$setuid(uid_t); - int sys$setgid(gid_t); - int sys$setresuid(uid_t, uid_t, uid_t); - int sys$setresgid(gid_t, gid_t, gid_t); - unsigned sys$alarm(unsigned seconds); - int sys$access(Userspace pathname, size_t path_length, int mode); - int sys$fcntl(int fd, int cmd, u32 extra_arg); - int sys$ioctl(int fd, unsigned request, FlatPtr arg); - int sys$mkdir(Userspace pathname, size_t path_length, mode_t mode); - clock_t sys$times(Userspace); - int sys$utime(Userspace pathname, size_t path_length, Userspace); - int sys$link(Userspace); - int sys$unlink(Userspace pathname, size_t path_length); - int sys$symlink(Userspace); - int sys$rmdir(Userspace pathname, size_t path_length); - int sys$mount(Userspace); - int sys$umount(Userspace mountpoint, size_t mountpoint_length); - int sys$chmod(Userspace pathname, size_t path_length, mode_t); - int sys$fchmod(int fd, mode_t); - int sys$chown(Userspace); - int sys$fchown(int fd, uid_t, gid_t); - int sys$socket(int domain, int type, int protocol); - int sys$bind(int sockfd, Userspace addr, socklen_t); - int sys$listen(int sockfd, int backlog); - int sys$accept(int sockfd, Userspace, Userspace); - int sys$connect(int sockfd, Userspace, socklen_t); - int sys$shutdown(int sockfd, int how); - ssize_t sys$sendmsg(int sockfd, Userspace, int flags); - ssize_t sys$recvmsg(int sockfd, Userspace, int flags); - int sys$getsockopt(Userspace); - int sys$setsockopt(Userspace); - int sys$getsockname(Userspace); - int sys$getpeername(Userspace); - int sys$sched_setparam(pid_t pid, Userspace); - int sys$sched_getparam(pid_t pid, Userspace); - int sys$create_thread(void* (*)(void*), Userspace); - void sys$exit_thread(Userspace); - int sys$join_thread(pid_t tid, Userspace exit_value); - int sys$detach_thread(pid_t tid); - int sys$set_thread_name(pid_t tid, Userspace buffer, size_t buffer_size); - int sys$get_thread_name(pid_t tid, Userspace buffer, size_t buffer_size); - int sys$rename(Userspace); - int sys$mknod(Userspace); - int sys$halt(); - int sys$reboot(); - int sys$realpath(Userspace); - ssize_t sys$getrandom(Userspace, size_t, unsigned int); - int sys$getkeymap(Userspace); - int sys$setkeymap(Userspace); - int sys$module_load(Userspace path, size_t path_length); - int sys$module_unload(Userspace name, size_t name_length); - int sys$profiling_enable(pid_t); - int sys$profiling_disable(pid_t); - int sys$futex(Userspace); - int sys$chroot(Userspace path, size_t path_length, int mount_flags); - int sys$pledge(Userspace); - int sys$unveil(Userspace); - int sys$perf_event(int type, FlatPtr arg1, FlatPtr arg2); - int sys$get_stack_bounds(FlatPtr* stack_base, size_t* stack_size); - int sys$ptrace(Userspace); - int sys$sendfd(int sockfd, int fd); - int sys$recvfd(int sockfd, int options); - long sys$sysconf(int name); - int sys$disown(ProcessID); - FlatPtr sys$allocate_tls(size_t); - int sys$prctl(int option, FlatPtr arg1, FlatPtr arg2); - int sys$set_coredump_metadata(Userspace); - void sys$abort(); - int sys$anon_create(size_t, int options); + KResultOr sys$sigreturn(RegisterState& registers); + KResultOr sys$waitid(Userspace); + KResultOr sys$mmap(Userspace); + KResultOr sys$mremap(Userspace); + KResultOr sys$munmap(void*, size_t size); + KResultOr sys$set_mmap_name(Userspace); + KResultOr sys$mprotect(void*, size_t, int prot); + KResultOr sys$madvise(void*, size_t, int advice); + KResultOr sys$msyscall(void*); + KResultOr sys$purge(int mode); + KResultOr sys$select(const Syscall::SC_select_params*); + KResultOr sys$poll(Userspace); + KResultOr sys$get_dir_entries(int fd, void*, ssize_t); + KResultOr sys$getcwd(Userspace, size_t); + KResultOr sys$chdir(Userspace, size_t); + KResultOr sys$fchdir(int fd); + KResultOr sys$adjtime(Userspace, Userspace); + KResultOr sys$gettimeofday(Userspace); + KResultOr sys$clock_gettime(clockid_t, Userspace); + KResultOr sys$clock_settime(clockid_t, Userspace); + KResultOr sys$clock_nanosleep(Userspace); + KResultOr sys$gethostname(Userspace, ssize_t); + KResultOr sys$sethostname(Userspace, ssize_t); + KResultOr sys$uname(Userspace); + KResultOr sys$readlink(Userspace); + KResultOr sys$ttyname(int fd, Userspace, size_t); + KResultOr sys$ptsname(int fd, Userspace, size_t); + KResultOr sys$fork(RegisterState&); + KResultOr sys$execve(Userspace); + KResultOr sys$dup2(int old_fd, int new_fd); + KResultOr sys$sigaction(int signum, const sigaction* act, sigaction* old_act); + KResultOr sys$sigprocmask(int how, Userspace set, Userspace old_set); + KResultOr sys$sigpending(Userspace); + KResultOr sys$getgroups(ssize_t, Userspace); + KResultOr sys$setgroups(ssize_t, Userspace); + KResultOr sys$pipe(int pipefd[2], int flags); + KResultOr sys$killpg(pid_t pgrp, int sig); + KResultOr sys$seteuid(uid_t); + KResultOr sys$setegid(gid_t); + KResultOr sys$setuid(uid_t); + KResultOr sys$setgid(gid_t); + KResultOr sys$setresuid(uid_t, uid_t, uid_t); + KResultOr sys$setresgid(gid_t, gid_t, gid_t); + KResultOr sys$alarm(unsigned seconds); + KResultOr sys$access(Userspace pathname, size_t path_length, int mode); + KResultOr sys$fcntl(int fd, int cmd, u32 extra_arg); + KResultOr sys$ioctl(int fd, unsigned request, FlatPtr arg); + KResultOr sys$mkdir(Userspace pathname, size_t path_length, mode_t mode); + KResultOr sys$times(Userspace); + KResultOr sys$utime(Userspace pathname, size_t path_length, Userspace); + KResultOr sys$link(Userspace); + KResultOr sys$unlink(Userspace pathname, size_t path_length); + KResultOr sys$symlink(Userspace); + KResultOr sys$rmdir(Userspace pathname, size_t path_length); + KResultOr sys$mount(Userspace); + KResultOr sys$umount(Userspace mountpoint, size_t mountpoint_length); + KResultOr sys$chmod(Userspace pathname, size_t path_length, mode_t); + KResultOr sys$fchmod(int fd, mode_t); + KResultOr sys$chown(Userspace); + KResultOr sys$fchown(int fd, uid_t, gid_t); + KResultOr sys$socket(int domain, int type, int protocol); + KResultOr sys$bind(int sockfd, Userspace addr, socklen_t); + KResultOr sys$listen(int sockfd, int backlog); + KResultOr sys$accept(int sockfd, Userspace, Userspace); + KResultOr sys$connect(int sockfd, Userspace, socklen_t); + KResultOr sys$shutdown(int sockfd, int how); + KResultOr sys$sendmsg(int sockfd, Userspace, int flags); + KResultOr sys$recvmsg(int sockfd, Userspace, int flags); + KResultOr sys$getsockopt(Userspace); + KResultOr sys$setsockopt(Userspace); + KResultOr sys$getsockname(Userspace); + KResultOr sys$getpeername(Userspace); + KResultOr sys$sched_setparam(pid_t pid, Userspace); + KResultOr sys$sched_getparam(pid_t pid, Userspace); + KResultOr sys$create_thread(void* (*)(void*), Userspace); + [[noreturn]] void sys$exit_thread(Userspace); + KResultOr sys$join_thread(pid_t tid, Userspace exit_value); + KResultOr sys$detach_thread(pid_t tid); + KResultOr sys$set_thread_name(pid_t tid, Userspace buffer, size_t buffer_size); + KResultOr sys$get_thread_name(pid_t tid, Userspace buffer, size_t buffer_size); + KResultOr sys$rename(Userspace); + KResultOr sys$mknod(Userspace); + KResultOr sys$halt(); + KResultOr sys$reboot(); + KResultOr sys$realpath(Userspace); + KResultOr sys$getrandom(Userspace, size_t, unsigned int); + KResultOr sys$getkeymap(Userspace); + KResultOr sys$setkeymap(Userspace); + KResultOr sys$module_load(Userspace path, size_t path_length); + KResultOr sys$module_unload(Userspace name, size_t name_length); + KResultOr sys$profiling_enable(pid_t); + KResultOr sys$profiling_disable(pid_t); + KResultOr sys$futex(Userspace); + KResultOr sys$chroot(Userspace path, size_t path_length, int mount_flags); + KResultOr sys$pledge(Userspace); + KResultOr sys$unveil(Userspace); + KResultOr sys$perf_event(int type, FlatPtr arg1, FlatPtr arg2); + KResultOr sys$get_stack_bounds(FlatPtr* stack_base, size_t* stack_size); + KResultOr sys$ptrace(Userspace); + KResultOr sys$sendfd(int sockfd, int fd); + KResultOr sys$recvfd(int sockfd, int options); + KResultOr sys$sysconf(int name); + KResultOr sys$disown(ProcessID); + KResultOr sys$allocate_tls(size_t); + KResultOr sys$prctl(int option, FlatPtr arg1, FlatPtr arg2); + KResultOr sys$set_coredump_metadata(Userspace); + [[noreturn]] void sys$abort(); + KResultOr sys$anon_create(size_t, int options); template int get_sock_or_peer_name(const Params&); @@ -479,7 +479,7 @@ private: bool dump_perfcore(); KResult do_exec(NonnullRefPtr main_program_description, Vector arguments, Vector environment, RefPtr interpreter_description, Thread*& new_main_thread, u32& prev_flags, const Elf32_Ehdr& main_program_header); - ssize_t do_write(FileDescription&, const UserOrKernelBuffer&, size_t); + KResultOr do_write(FileDescription&, const UserOrKernelBuffer&, size_t); KResultOr> find_elf_interpreter_for_executable(const String& path, const Elf32_Ehdr& elf_header, int nread, size_t file_size); diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 47db964964..90921e0721 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -69,7 +69,7 @@ asm( namespace Syscall { -static int handle(RegisterState&, u32 function, u32 arg1, u32 arg2, u32 arg3); +static KResultOr handle(RegisterState&, FlatPtr function, FlatPtr arg1, FlatPtr arg2, FlatPtr arg3); UNMAP_AFTER_INIT void initialize() { @@ -78,14 +78,15 @@ UNMAP_AFTER_INIT void initialize() } #pragma GCC diagnostic ignored "-Wcast-function-type" -typedef int (Process::*Handler)(u32, u32, u32); +typedef KResultOr (Process::*Handler)(FlatPtr, FlatPtr, FlatPtr); +typedef KResultOr (Process::*HandlerWithRegisterState)(RegisterState&); #define __ENUMERATE_SYSCALL(x) reinterpret_cast(&Process::sys$##x), static Handler s_syscall_table[] = { ENUMERATE_SYSCALLS(__ENUMERATE_SYSCALL) }; #undef __ENUMERATE_SYSCALL -int handle(RegisterState& regs, u32 function, u32 arg1, u32 arg2, u32 arg3) +KResultOr handle(RegisterState& regs, FlatPtr function, FlatPtr arg1, FlatPtr arg2, FlatPtr arg3) { VERIFY_INTERRUPTS_ENABLED(); auto current_thread = Thread::current(); @@ -102,18 +103,17 @@ int handle(RegisterState& regs, u32 function, u32 arg1, u32 arg2, u32 arg3) } if (function == SC_exit) - process.sys$exit((int)arg1); + process.sys$exit(arg1); else process.sys$exit_thread(arg1); VERIFY_NOT_REACHED(); - return 0; } - if (function == SC_fork) - return process.sys$fork(regs); - - if (function == SC_sigreturn) - return process.sys$sigreturn(regs); + if (function == SC_fork || function == SC_sigreturn) { + // These syscalls want the RegisterState& rather than individual parameters. + auto handler = (HandlerWithRegisterState)s_syscall_table[function]; + return (process.*(handler))(regs); + } if (function >= Function::__Count) { dbgln("Unknown syscall {} requested ({:08x}, {:08x}, {:08x})", function, arg1, arg2, arg3); @@ -162,7 +162,7 @@ void syscall_handler(TrapFrame* trap) asm volatile("" : "=m"(*ptr)); - static constexpr u32 iopl_mask = 3u << 12; + static constexpr FlatPtr iopl_mask = 3u << 12; if ((regs.eflags & (iopl_mask)) != 0) { PANIC("Syscall from process with IOPL != 0"); @@ -192,11 +192,16 @@ void syscall_handler(TrapFrame* trap) handle_crash(regs, "Syscall from non-syscall region", SIGSEGV); } - u32 function = regs.eax; - u32 arg1 = regs.edx; - u32 arg2 = regs.ecx; - u32 arg3 = regs.ebx; - regs.eax = Syscall::handle(regs, function, arg1, arg2, arg3); + auto function = regs.eax; + auto arg1 = regs.edx; + auto arg2 = regs.ecx; + auto arg3 = regs.ebx; + + auto result = Syscall::handle(regs, function, arg1, arg2, arg3); + if (result.is_error()) + regs.eax = result.error(); + else + regs.eax = result.value(); process.big_lock().unlock(); diff --git a/Kernel/Syscalls/access.cpp b/Kernel/Syscalls/access.cpp index 6af702166c..aaf1c1df24 100644 --- a/Kernel/Syscalls/access.cpp +++ b/Kernel/Syscalls/access.cpp @@ -30,7 +30,7 @@ namespace Kernel { -int Process::sys$access(Userspace user_path, size_t path_length, int mode) +KResultOr Process::sys$access(Userspace user_path, size_t path_length, int mode) { REQUIRE_PROMISE(rpath); auto path = get_syscall_path_argument(user_path, path_length); diff --git a/Kernel/Syscalls/alarm.cpp b/Kernel/Syscalls/alarm.cpp index 8282572acc..e195de65fd 100644 --- a/Kernel/Syscalls/alarm.cpp +++ b/Kernel/Syscalls/alarm.cpp @@ -29,7 +29,7 @@ namespace Kernel { -unsigned Process::sys$alarm(unsigned seconds) +KResultOr Process::sys$alarm(unsigned seconds) { REQUIRE_PROMISE(stdio); unsigned previous_alarm_remaining = 0; diff --git a/Kernel/Syscalls/anon_create.cpp b/Kernel/Syscalls/anon_create.cpp index 6756b9688b..858aea5da6 100644 --- a/Kernel/Syscalls/anon_create.cpp +++ b/Kernel/Syscalls/anon_create.cpp @@ -31,15 +31,15 @@ namespace Kernel { -int Process::sys$anon_create(size_t size, int options) +KResultOr Process::sys$anon_create(size_t size, int options) { REQUIRE_PROMISE(stdio); if (!size) - return -EINVAL; + return EINVAL; if (size % PAGE_SIZE) - return -EINVAL; + return EINVAL; int new_fd = alloc_fd(); if (new_fd < 0) @@ -47,7 +47,7 @@ int Process::sys$anon_create(size_t size, int options) auto vmobject = AnonymousVMObject::create_with_size(size, AllocationStrategy::Reserve); if (!vmobject) - return -ENOMEM; + return ENOMEM; auto anon_file = AnonymousFile::create(vmobject.release_nonnull()); auto description_or_error = FileDescription::create(*anon_file); diff --git a/Kernel/Syscalls/beep.cpp b/Kernel/Syscalls/beep.cpp index 14043910fe..a94df54079 100644 --- a/Kernel/Syscalls/beep.cpp +++ b/Kernel/Syscalls/beep.cpp @@ -29,13 +29,13 @@ namespace Kernel { -int Process::sys$beep() +KResultOr Process::sys$beep() { PCSpeaker::tone_on(440); auto result = Thread::current()->sleep({ 0, 200 }); PCSpeaker::tone_off(); if (result.was_interrupted()) - return -EINTR; + return EINTR; return 0; } diff --git a/Kernel/Syscalls/chdir.cpp b/Kernel/Syscalls/chdir.cpp index 23555e2cff..7df05a0a25 100644 --- a/Kernel/Syscalls/chdir.cpp +++ b/Kernel/Syscalls/chdir.cpp @@ -31,7 +31,7 @@ namespace Kernel { -int Process::sys$chdir(Userspace user_path, size_t path_length) +KResultOr Process::sys$chdir(Userspace user_path, size_t path_length) { REQUIRE_PROMISE(rpath); auto path = get_syscall_path_argument(user_path, path_length); @@ -44,24 +44,24 @@ int Process::sys$chdir(Userspace user_path, size_t path_length) return 0; } -int Process::sys$fchdir(int fd) +KResultOr Process::sys$fchdir(int fd) { REQUIRE_PROMISE(stdio); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; if (!description->is_directory()) - return -ENOTDIR; + return ENOTDIR; if (!description->metadata().may_execute(*this)) - return -EACCES; + return EACCES; m_cwd = description->custody(); return 0; } -int Process::sys$getcwd(Userspace buffer, size_t size) +KResultOr Process::sys$getcwd(Userspace buffer, size_t size) { REQUIRE_PROMISE(rpath); @@ -70,7 +70,7 @@ int Process::sys$getcwd(Userspace buffer, size_t size) size_t ideal_size = path.length() + 1; auto size_to_copy = min(ideal_size, size); if (!copy_to_user(buffer, path.characters(), size_to_copy)) - return -EFAULT; + return EFAULT; // Note: we return the whole size here, not the copied size. return ideal_size; } diff --git a/Kernel/Syscalls/chmod.cpp b/Kernel/Syscalls/chmod.cpp index 2c6da91ca2..e0bcc80efa 100644 --- a/Kernel/Syscalls/chmod.cpp +++ b/Kernel/Syscalls/chmod.cpp @@ -31,7 +31,7 @@ namespace Kernel { -int Process::sys$chmod(Userspace user_path, size_t path_length, mode_t mode) +KResultOr Process::sys$chmod(Userspace user_path, size_t path_length, mode_t mode) { REQUIRE_PROMISE(fattr); auto path = get_syscall_path_argument(user_path, path_length); @@ -40,12 +40,12 @@ int Process::sys$chmod(Userspace user_path, size_t path_length, mod return VFS::the().chmod(path.value(), mode, current_directory()); } -int Process::sys$fchmod(int fd, mode_t mode) +KResultOr Process::sys$fchmod(int fd, mode_t mode) { REQUIRE_PROMISE(fattr); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; return description->chmod(mode); } diff --git a/Kernel/Syscalls/chown.cpp b/Kernel/Syscalls/chown.cpp index e07ab19f8a..51b447922d 100644 --- a/Kernel/Syscalls/chown.cpp +++ b/Kernel/Syscalls/chown.cpp @@ -29,21 +29,21 @@ namespace Kernel { -int Process::sys$fchown(int fd, uid_t uid, gid_t gid) +KResultOr Process::sys$fchown(int fd, uid_t uid, gid_t gid) { REQUIRE_PROMISE(chown); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; return description->chown(uid, gid); } -int Process::sys$chown(Userspace user_params) +KResultOr Process::sys$chown(Userspace user_params) { REQUIRE_PROMISE(chown); Syscall::SC_chown_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto path = get_syscall_path_argument(params.path); if (path.is_error()) return path.error(); diff --git a/Kernel/Syscalls/chroot.cpp b/Kernel/Syscalls/chroot.cpp index 73ba127967..27df74b80f 100644 --- a/Kernel/Syscalls/chroot.cpp +++ b/Kernel/Syscalls/chroot.cpp @@ -31,10 +31,10 @@ namespace Kernel { -int Process::sys$chroot(Userspace user_path, size_t path_length, int mount_flags) +KResultOr Process::sys$chroot(Userspace user_path, size_t path_length, int mount_flags) { if (!is_superuser()) - return -EPERM; + return EPERM; REQUIRE_PROMISE(chroot); auto path = get_syscall_path_argument(user_path, path_length); if (path.is_error()) diff --git a/Kernel/Syscalls/clock.cpp b/Kernel/Syscalls/clock.cpp index 557d9376ce..f70d457293 100644 --- a/Kernel/Syscalls/clock.cpp +++ b/Kernel/Syscalls/clock.cpp @@ -30,7 +30,7 @@ namespace Kernel { -int Process::sys$clock_gettime(clockid_t clock_id, Userspace user_ts) +KResultOr Process::sys$clock_gettime(clockid_t clock_id, Userspace user_ts) { REQUIRE_PROMISE(stdio); @@ -39,42 +39,42 @@ int Process::sys$clock_gettime(clockid_t clock_id, Userspace user_ts) return ts.error(); if (!copy_to_user(user_ts, &ts.value())) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$clock_settime(clockid_t clock_id, Userspace user_ts) +KResultOr Process::sys$clock_settime(clockid_t clock_id, Userspace user_ts) { REQUIRE_PROMISE(settime); if (!is_superuser()) - return -EPERM; + return EPERM; timespec ts; if (!copy_from_user(&ts, user_ts)) - return -EFAULT; + return EFAULT; switch (clock_id) { case CLOCK_REALTIME: TimeManagement::the().set_epoch_time(ts); break; default: - return -EINVAL; + return EINVAL; } return 0; } -int Process::sys$clock_nanosleep(Userspace user_params) +KResultOr Process::sys$clock_nanosleep(Userspace user_params) { REQUIRE_PROMISE(stdio); Syscall::SC_clock_nanosleep_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; timespec requested_sleep; if (!copy_from_user(&requested_sleep, params.requested_sleep)) - return -EFAULT; + return EFAULT; bool is_absolute; switch (params.flags) { @@ -85,11 +85,11 @@ int Process::sys$clock_nanosleep(Userspacesleep(params.clock_id, requested_sleep, &remaining_sleep).was_interrupted(); if (was_interrupted && params.remaining_sleep && !copy_to_user(params.remaining_sleep, &remaining_sleep)) - return -EFAULT; + return EFAULT; } if (was_interrupted) - return -EINTR; + return EINTR; return 0; } -int Process::sys$adjtime(Userspace user_delta, Userspace user_old_delta) +KResultOr Process::sys$adjtime(Userspace user_delta, Userspace user_old_delta) { if (user_old_delta) { timespec old_delta_ts = TimeManagement::the().remaining_epoch_time_adjustment(); timeval old_delta; timespec_to_timeval(old_delta_ts, old_delta); if (!copy_to_user(user_old_delta, &old_delta)) - return -EFAULT; + return EFAULT; } if (user_delta) { REQUIRE_PROMISE(settime); if (!is_superuser()) - return -EPERM; + return EPERM; timeval delta; if (!copy_from_user(&delta, user_delta)) - return -EFAULT; + return EFAULT; if (delta.tv_usec < 0 || delta.tv_usec >= 1'000'000) - return -EINVAL; + return EINVAL; timespec delta_ts; timeval_to_timespec(delta, delta_ts); @@ -134,12 +134,12 @@ int Process::sys$adjtime(Userspace user_delta, Userspace user_tv) +KResultOr Process::sys$gettimeofday(Userspace user_tv) { REQUIRE_PROMISE(stdio); auto tv = kgettimeofday(); if (!copy_to_user(user_tv, &tv)) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/debug.cpp b/Kernel/Syscalls/debug.cpp index 2753b954e1..09d3d57830 100644 --- a/Kernel/Syscalls/debug.cpp +++ b/Kernel/Syscalls/debug.cpp @@ -31,26 +31,26 @@ namespace Kernel { -int Process::sys$dump_backtrace() +KResultOr Process::sys$dump_backtrace() { dump_backtrace(); return 0; } -int Process::sys$dbgputch(u8 ch) +KResultOr Process::sys$dbgputch(u8 ch) { IO::out8(0xe9, ch); return 0; } -int Process::sys$dbgputstr(Userspace characters, int length) +KResultOr Process::sys$dbgputstr(Userspace characters, int length) { if (length <= 0) return 0; auto buffer = UserOrKernelBuffer::for_user_buffer(characters, length); if (!buffer.has_value()) - return -EFAULT; + return EFAULT; ssize_t nread = buffer.value().read_buffered<1024>(length, [&](const u8* buffer, size_t buffer_size) { for (size_t i = 0; i < buffer_size; ++i) IO::out8(0xe9, buffer[i]); diff --git a/Kernel/Syscalls/disown.cpp b/Kernel/Syscalls/disown.cpp index 3c7ddf5eab..0a0408dc39 100644 --- a/Kernel/Syscalls/disown.cpp +++ b/Kernel/Syscalls/disown.cpp @@ -28,14 +28,14 @@ namespace Kernel { -int Process::sys$disown(ProcessID pid) +KResultOr Process::sys$disown(ProcessID pid) { REQUIRE_PROMISE(proc); auto process = Process::from_pid(pid); if (!process) - return -ESRCH; + return ESRCH; if (process->ppid() != this->pid()) - return -ECHILD; + return ECHILD; process->m_ppid = 0; process->disowned_by_waiter(*this); return 0; diff --git a/Kernel/Syscalls/dup2.cpp b/Kernel/Syscalls/dup2.cpp index 7e46f10e31..fc1c4881d1 100644 --- a/Kernel/Syscalls/dup2.cpp +++ b/Kernel/Syscalls/dup2.cpp @@ -29,16 +29,16 @@ namespace Kernel { -int Process::sys$dup2(int old_fd, int new_fd) +KResultOr Process::sys$dup2(int old_fd, int new_fd) { REQUIRE_PROMISE(stdio); auto description = file_description(old_fd); if (!description) - return -EBADF; + return EBADF; if (old_fd == new_fd) return 0; if (new_fd < 0 || new_fd >= m_max_open_file_descriptors) - return -EINVAL; + return EINVAL; m_fds[new_fd].set(*description); return new_fd; } diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 41c76a8b85..03de8d0df6 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -214,7 +214,7 @@ static KResultOr get_interpreter_load_offset(const Elf32_Ehdr& main_pro } if (main_program_header.e_type != ET_EXEC) - return -EINVAL; + return EINVAL; auto main_program_load_range_result = get_required_load_range(main_program_description); if (main_program_load_range_result.is_error()) @@ -245,7 +245,7 @@ static KResultOr get_interpreter_load_offset(const Elf32_Ehdr& main_pro // If main program is too big and leaves us without enough space for adequate loader randmoization if (selected_range.end - selected_range.start < minimum_interpreter_load_offset_randomization_size) - return -E2BIG; + return E2BIG; return random_load_offset_in_range(selected_range.start, selected_range.end - selected_range.start); } @@ -876,7 +876,7 @@ KResult Process::exec(String path, Vector arguments, Vector envi return KSuccess; } -int Process::sys$execve(Userspace user_params) +KResultOr Process::sys$execve(Userspace user_params) { REQUIRE_PROMISE(exec); @@ -884,10 +884,10 @@ int Process::sys$execve(Userspace user_params) // On success, the kernel stack will be lost. Syscall::SC_execve_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; if (params.arguments.length > ARG_MAX || params.environment.length > ARG_MAX) - return -E2BIG; + return E2BIG; String path; { @@ -919,11 +919,11 @@ int Process::sys$execve(Userspace user_params) Vector arguments; if (!copy_user_strings(params.arguments, arguments)) - return -EFAULT; + return EFAULT; Vector environment; if (!copy_user_strings(params.environment, environment)) - return -EFAULT; + return EFAULT; auto result = exec(move(path), move(arguments), move(environment)); VERIFY(result.is_error()); // We should never continue after a successful exec! diff --git a/Kernel/Syscalls/fcntl.cpp b/Kernel/Syscalls/fcntl.cpp index 60e0ced3be..7c9cae3646 100644 --- a/Kernel/Syscalls/fcntl.cpp +++ b/Kernel/Syscalls/fcntl.cpp @@ -30,20 +30,20 @@ namespace Kernel { -int Process::sys$fcntl(int fd, int cmd, u32 arg) +KResultOr Process::sys$fcntl(int fd, int cmd, u32 arg) { REQUIRE_PROMISE(stdio); dbgln_if(IO_DEBUG, "sys$fcntl: fd={}, cmd={}, arg={}", fd, cmd, arg); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; // NOTE: The FD flags are not shared between FileDescription objects. // This means that dup() doesn't copy the FD_CLOEXEC flag! switch (cmd) { case F_DUPFD: { int arg_fd = (int)arg; if (arg_fd < 0) - return -EINVAL; + return EINVAL; int new_fd = alloc_fd(arg_fd); if (new_fd < 0) return new_fd; @@ -63,7 +63,7 @@ int Process::sys$fcntl(int fd, int cmd, u32 arg) case F_ISTTY: return description->is_tty(); default: - return -EINVAL; + return EINVAL; } return 0; } diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index 44171c2776..4b462bb672 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -32,13 +32,13 @@ namespace Kernel { -pid_t Process::sys$fork(RegisterState& regs) +KResultOr Process::sys$fork(RegisterState& regs) { REQUIRE_PROMISE(proc); RefPtr child_first_thread; auto child = adopt(*new Process(child_first_thread, m_name, m_uid, m_gid, m_pid, m_is_kernel_process, m_cwd, m_executable, m_tty, this)); if (!child_first_thread) - return -ENOMEM; + return ENOMEM; child->m_root_directory = m_root_directory; child->m_root_directory_relative_to_global_root = m_root_directory_relative_to_global_root; child->m_promises = m_promises; @@ -85,7 +85,7 @@ pid_t Process::sys$fork(RegisterState& regs) if (!region_clone) { dbgln("fork: Cannot clone region, insufficient memory"); // TODO: tear down new process? - return -ENOMEM; + return ENOMEM; } auto& child_region = child->space().add_region(region_clone.release_nonnull()); diff --git a/Kernel/Syscalls/ftruncate.cpp b/Kernel/Syscalls/ftruncate.cpp index 3b04a16e53..6fc9afcc79 100644 --- a/Kernel/Syscalls/ftruncate.cpp +++ b/Kernel/Syscalls/ftruncate.cpp @@ -29,16 +29,16 @@ namespace Kernel { -int Process::sys$ftruncate(int fd, off_t length) +KResultOr Process::sys$ftruncate(int fd, off_t length) { REQUIRE_PROMISE(stdio); if (length < 0) - return -EINVAL; + return EINVAL; auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; if (!description->is_writable()) - return -EBADF; + return EBADF; return description->truncate(static_cast(length)); } diff --git a/Kernel/Syscalls/futex.cpp b/Kernel/Syscalls/futex.cpp index 1240c7ee3e..dd1aa5c92c 100644 --- a/Kernel/Syscalls/futex.cpp +++ b/Kernel/Syscalls/futex.cpp @@ -102,13 +102,13 @@ void Process::clear_futex_queues_on_exec() m_futex_queues.clear(); } -int Process::sys$futex(Userspace user_params) +KResultOr Process::sys$futex(Userspace user_params) { REQUIRE_PROMISE(thread); Syscall::SC_futex_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; Thread::BlockTimeout timeout; u32 cmd = params.futex_op & FUTEX_CMD_MASK; @@ -120,7 +120,7 @@ int Process::sys$futex(Userspace user_params) if (params.timeout) { timespec ts_stimeout { 0, 0 }; if (!copy_from_user(&ts_stimeout, params.timeout)) - return -EFAULT; + return EFAULT; clockid_t clock_id = (params.futex_op & FUTEX_CLOCK_REALTIME) ? CLOCK_REALTIME_COARSE : CLOCK_MONOTONIC_COARSE; bool is_absolute = cmd != FUTEX_WAIT; timeout = Thread::BlockTimeout(is_absolute, &ts_stimeout, nullptr, clock_id); @@ -146,7 +146,7 @@ int Process::sys$futex(Userspace user_params) if (!is_private) { auto region = space().find_region_containing(Range { VirtualAddress { user_address_or_offset }, sizeof(u32) }); if (!region) - return -EFAULT; + return EFAULT; vmobject = region->vmobject(); user_address_or_offset = region->offset_in_vmobject_from_vaddr(VirtualAddress(user_address_or_offset)); @@ -156,7 +156,7 @@ int Process::sys$futex(Userspace user_params) case FUTEX_WAKE_OP: { auto region2 = space().find_region_containing(Range { VirtualAddress { user_address_or_offset2 }, sizeof(u32) }); if (!region2) - return -EFAULT; + return EFAULT; vmobject2 = region2->vmobject(); user_address_or_offset2 = region->offset_in_vmobject_from_vaddr(VirtualAddress(user_address_or_offset2)); break; @@ -226,10 +226,10 @@ int Process::sys$futex(Userspace user_params) auto do_wait = [&](u32 bitset) -> int { auto user_value = user_atomic_load_relaxed(params.userspace_address); if (!user_value.has_value()) - return -EFAULT; + return EFAULT; if (user_value.value() != params.val) { dbgln("futex wait: EAGAIN. user value: {:p} @ {:p} != val: {}", user_value.value(), params.userspace_address, params.val); - return -EAGAIN; + return EAGAIN; } atomic_thread_fence(AK::MemoryOrder::memory_order_acquire); @@ -248,7 +248,7 @@ int Process::sys$futex(Userspace user_params) remove_futex_queue(vmobject, user_address_or_offset); } if (block_result == Thread::BlockResult::InterruptedByTimeout) { - return -ETIMEDOUT; + return ETIMEDOUT; } return 0; }; @@ -256,9 +256,9 @@ int Process::sys$futex(Userspace user_params) auto do_requeue = [&](Optional val3) -> int { auto user_value = user_atomic_load_relaxed(params.userspace_address); if (!user_value.has_value()) - return -EFAULT; + return EFAULT; if (val3.has_value() && val3.value() != user_value.value()) - return -EAGAIN; + return EAGAIN; atomic_thread_fence(AK::MemoryOrder::memory_order_acquire); int woken_or_requeued = 0; @@ -315,10 +315,10 @@ int Process::sys$futex(Userspace user_params) oldval = user_atomic_fetch_xor_relaxed(params.userspace_address2, op_arg); break; default: - return -EINVAL; + return EINVAL; } if (!oldval.has_value()) - return -EFAULT; + return EFAULT; atomic_thread_fence(AK::MemoryOrder::memory_order_acquire); int result = do_wake(vmobject.ptr(), user_address_or_offset, params.val, {}); if (params.val2 > 0) { @@ -343,7 +343,7 @@ int Process::sys$futex(Userspace user_params) compare_result = (oldval.value() >= _FUTEX_CMP_ARG(params.val3)); break; default: - return -EINVAL; + return EINVAL; } if (compare_result) result += do_wake(vmobject2.ptr(), user_address_or_offset2, params.val2, {}); @@ -360,16 +360,16 @@ int Process::sys$futex(Userspace user_params) case FUTEX_WAIT_BITSET: VERIFY(params.val3 != FUTEX_BITSET_MATCH_ANY); // we should have turned it into FUTEX_WAIT if (params.val3 == 0) - return -EINVAL; + return EINVAL; return do_wait(params.val3); case FUTEX_WAKE_BITSET: VERIFY(params.val3 != FUTEX_BITSET_MATCH_ANY); // we should have turned it into FUTEX_WAKE if (params.val3 == 0) - return -EINVAL; + return EINVAL; return do_wake(vmobject.ptr(), user_address_or_offset, params.val, params.val3); } - return -ENOSYS; + return ENOSYS; } } diff --git a/Kernel/Syscalls/get_dir_entries.cpp b/Kernel/Syscalls/get_dir_entries.cpp index a94bf584d3..627ab8456e 100644 --- a/Kernel/Syscalls/get_dir_entries.cpp +++ b/Kernel/Syscalls/get_dir_entries.cpp @@ -29,17 +29,17 @@ namespace Kernel { -ssize_t Process::sys$get_dir_entries(int fd, void* buffer, ssize_t size) +KResultOr Process::sys$get_dir_entries(int fd, void* buffer, ssize_t size) { REQUIRE_PROMISE(stdio); if (size < 0) - return -EINVAL; + return EINVAL; auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; auto user_buffer = UserOrKernelBuffer::for_user_buffer((u8*)buffer, size); if (!user_buffer.has_value()) - return -EFAULT; + return EFAULT; return description->get_dir_entries(user_buffer.value(), size); } diff --git a/Kernel/Syscalls/get_stack_bounds.cpp b/Kernel/Syscalls/get_stack_bounds.cpp index f187fdf667..9ffc5fece0 100644 --- a/Kernel/Syscalls/get_stack_bounds.cpp +++ b/Kernel/Syscalls/get_stack_bounds.cpp @@ -30,7 +30,7 @@ namespace Kernel { -int Process::sys$get_stack_bounds(FlatPtr* user_stack_base, size_t* user_stack_size) +KResultOr Process::sys$get_stack_bounds(FlatPtr* user_stack_base, size_t* user_stack_size) { FlatPtr stack_pointer = Thread::current()->get_register_dump_from_stack().userspace_esp; auto* stack_region = space().find_region_containing(Range { VirtualAddress(stack_pointer), 1 }); @@ -41,9 +41,9 @@ int Process::sys$get_stack_bounds(FlatPtr* user_stack_base, size_t* user_stack_s FlatPtr stack_base = stack_region->range().base().get(); size_t stack_size = stack_region->size(); if (!copy_to_user(user_stack_base, &stack_base)) - return -EFAULT; + return EFAULT; if (!copy_to_user(user_stack_size, &stack_size)) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/getrandom.cpp b/Kernel/Syscalls/getrandom.cpp index 37d9374659..555a52b2cb 100644 --- a/Kernel/Syscalls/getrandom.cpp +++ b/Kernel/Syscalls/getrandom.cpp @@ -33,15 +33,15 @@ namespace Kernel { // We don't use the flag yet, but we could use it for distinguishing // random source like Linux, unlike the OpenBSD equivalent. However, if we // do, we should be able of the caveats that Linux has dealt with. -ssize_t Process::sys$getrandom(Userspace buffer, size_t buffer_size, [[maybe_unused]] unsigned flags) +KResultOr Process::sys$getrandom(Userspace buffer, size_t buffer_size, [[maybe_unused]] unsigned flags) { REQUIRE_PROMISE(stdio); if (buffer_size <= 0) - return -EINVAL; + return EINVAL; auto data_buffer = UserOrKernelBuffer::for_user_buffer(buffer, buffer_size); if (!data_buffer.has_value()) - return -EFAULT; + return EFAULT; ssize_t nwritten = data_buffer.value().write_buffered<1024>(buffer_size, [&](u8* buffer, size_t buffer_bytes) { get_good_random_bytes(buffer, buffer_bytes); return (ssize_t)buffer_bytes; diff --git a/Kernel/Syscalls/getuid.cpp b/Kernel/Syscalls/getuid.cpp index 73889c8ca6..55957026b6 100644 --- a/Kernel/Syscalls/getuid.cpp +++ b/Kernel/Syscalls/getuid.cpp @@ -28,58 +28,58 @@ namespace Kernel { -uid_t Process::sys$getuid() +KResultOr Process::sys$getuid() { REQUIRE_PROMISE(stdio); return m_uid; } -gid_t Process::sys$getgid() +KResultOr Process::sys$getgid() { REQUIRE_PROMISE(stdio); return m_gid; } -uid_t Process::sys$geteuid() +KResultOr Process::sys$geteuid() { REQUIRE_PROMISE(stdio); return m_euid; } -gid_t Process::sys$getegid() +KResultOr Process::sys$getegid() { REQUIRE_PROMISE(stdio); return m_egid; } -int Process::sys$getresuid(Userspace ruid, Userspace euid, Userspace suid) +KResultOr Process::sys$getresuid(Userspace ruid, Userspace euid, Userspace suid) { REQUIRE_PROMISE(stdio); if (!copy_to_user(ruid, &m_uid) || !copy_to_user(euid, &m_euid) || !copy_to_user(suid, &m_suid)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$getresgid(Userspace rgid, Userspace egid, Userspace sgid) +KResultOr Process::sys$getresgid(Userspace rgid, Userspace egid, Userspace sgid) { REQUIRE_PROMISE(stdio); if (!copy_to_user(rgid, &m_gid) || !copy_to_user(egid, &m_egid) || !copy_to_user(sgid, &m_sgid)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$getgroups(ssize_t count, Userspace user_gids) +KResultOr Process::sys$getgroups(ssize_t count, Userspace user_gids) { REQUIRE_PROMISE(stdio); if (count < 0) - return -EINVAL; + return EINVAL; if (!count) return m_extra_gids.size(); if (count != (int)m_extra_gids.size()) - return -EINVAL; + return EINVAL; if (!copy_to_user(user_gids, m_extra_gids.data(), sizeof(gid_t) * count)) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/hostname.cpp b/Kernel/Syscalls/hostname.cpp index fa5c992b52..0e5aa48c93 100644 --- a/Kernel/Syscalls/hostname.cpp +++ b/Kernel/Syscalls/hostname.cpp @@ -31,32 +31,32 @@ namespace Kernel { extern String* g_hostname; extern Lock* g_hostname_lock; -int Process::sys$gethostname(Userspace buffer, ssize_t size) +KResultOr Process::sys$gethostname(Userspace buffer, ssize_t size) { REQUIRE_PROMISE(stdio); if (size < 0) - return -EINVAL; + return EINVAL; LOCKER(*g_hostname_lock, Lock::Mode::Shared); if ((size_t)size < (g_hostname->length() + 1)) - return -ENAMETOOLONG; + return ENAMETOOLONG; if (!copy_to_user(buffer, g_hostname->characters(), g_hostname->length() + 1)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$sethostname(Userspace hostname, ssize_t length) +KResultOr Process::sys$sethostname(Userspace hostname, ssize_t length) { REQUIRE_NO_PROMISES; if (!is_superuser()) - return -EPERM; + return EPERM; if (length < 0) - return -EINVAL; + return EINVAL; LOCKER(*g_hostname_lock, Lock::Mode::Exclusive); if (length > 64) - return -ENAMETOOLONG; + return ENAMETOOLONG; auto copied_hostname = copy_string_from_user(hostname, length); if (copied_hostname.is_null()) - return -EFAULT; + return EFAULT; *g_hostname = move(copied_hostname); return 0; } diff --git a/Kernel/Syscalls/ioctl.cpp b/Kernel/Syscalls/ioctl.cpp index 52af998816..2d06bffa34 100644 --- a/Kernel/Syscalls/ioctl.cpp +++ b/Kernel/Syscalls/ioctl.cpp @@ -29,11 +29,11 @@ namespace Kernel { -int Process::sys$ioctl(int fd, unsigned request, FlatPtr arg) +KResultOr Process::sys$ioctl(int fd, unsigned request, FlatPtr arg) { auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; return description->file().ioctl(*description, request, arg); } diff --git a/Kernel/Syscalls/keymap.cpp b/Kernel/Syscalls/keymap.cpp index 4fb0623e38..e22a8dd377 100644 --- a/Kernel/Syscalls/keymap.cpp +++ b/Kernel/Syscalls/keymap.cpp @@ -31,68 +31,68 @@ namespace Kernel { constexpr size_t map_name_max_size = 50; -int Process::sys$setkeymap(Userspace user_params) +KResultOr Process::sys$setkeymap(Userspace user_params) { REQUIRE_PROMISE(setkeymap); if (!is_superuser()) - return -EPERM; + return EPERM; Syscall::SC_setkeymap_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; Keyboard::CharacterMapData character_map_data; if (!copy_n_from_user(character_map_data.map, params.map, CHAR_MAP_SIZE)) - return -EFAULT; + return EFAULT; if (!copy_n_from_user(character_map_data.shift_map, params.shift_map, CHAR_MAP_SIZE)) - return -EFAULT; + return EFAULT; if (!copy_n_from_user(character_map_data.alt_map, params.alt_map, CHAR_MAP_SIZE)) - return -EFAULT; + return EFAULT; if (!copy_n_from_user(character_map_data.altgr_map, params.altgr_map, CHAR_MAP_SIZE)) - return -EFAULT; + return EFAULT; if (!copy_n_from_user(character_map_data.shift_altgr_map, params.shift_altgr_map, CHAR_MAP_SIZE)) - return -EFAULT; + return EFAULT; auto map_name = get_syscall_path_argument(params.map_name); if (map_name.is_error()) { return map_name.error(); } if (map_name.value().length() > map_name_max_size) { - return -ENAMETOOLONG; + return ENAMETOOLONG; } KeyboardDevice::the().set_maps(character_map_data, map_name.value()); return 0; } -int Process::sys$getkeymap(Userspace user_params) +KResultOr Process::sys$getkeymap(Userspace user_params) { REQUIRE_PROMISE(getkeymap); Syscall::SC_getkeymap_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; String keymap_name = KeyboardDevice::the().keymap_name(); const Keyboard::CharacterMapData& character_maps = KeyboardDevice::the().character_maps(); if (!copy_to_user(params.map, character_maps.map, CHAR_MAP_SIZE * sizeof(u32))) - return -EFAULT; + return EFAULT; if (!copy_to_user(params.shift_map, character_maps.shift_map, CHAR_MAP_SIZE * sizeof(u32))) - return -EFAULT; + return EFAULT; if (!copy_to_user(params.alt_map, character_maps.alt_map, CHAR_MAP_SIZE * sizeof(u32))) - return -EFAULT; + return EFAULT; if (!copy_to_user(params.altgr_map, character_maps.altgr_map, CHAR_MAP_SIZE * sizeof(u32))) - return -EFAULT; + return EFAULT; if (!copy_to_user(params.shift_altgr_map, character_maps.shift_altgr_map, CHAR_MAP_SIZE * sizeof(u32))) - return -EFAULT; + return EFAULT; if (params.map_name.size < keymap_name.length()) - return -ENAMETOOLONG; + return ENAMETOOLONG; if (!copy_to_user(params.map_name.data, keymap_name.characters(), keymap_name.length())) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/kill.cpp b/Kernel/Syscalls/kill.cpp index e8b8978799..1a75d77c06 100644 --- a/Kernel/Syscalls/kill.cpp +++ b/Kernel/Syscalls/kill.cpp @@ -117,7 +117,7 @@ KResult Process::do_killself(int signal) return KSuccess; } -int Process::sys$kill(pid_t pid_or_pgid, int signal) +KResultOr Process::sys$kill(pid_t pid_or_pgid, int signal) { if (pid_or_pgid == m_pid.value()) REQUIRE_PROMISE(stdio); @@ -125,10 +125,10 @@ int Process::sys$kill(pid_t pid_or_pgid, int signal) REQUIRE_PROMISE(proc); if (signal < 0 || signal >= 32) - return -EINVAL; + return EINVAL; if (pid_or_pgid < -1) { if (pid_or_pgid == NumericLimits::min()) - return -EINVAL; + return EINVAL; return do_killpg(-pid_or_pgid, signal); } if (pid_or_pgid == -1) @@ -140,17 +140,17 @@ int Process::sys$kill(pid_t pid_or_pgid, int signal) ScopedSpinLock lock(g_processes_lock); auto peer = Process::from_pid(pid_or_pgid); if (!peer) - return -ESRCH; + return ESRCH; return do_kill(*peer, signal); } -int Process::sys$killpg(pid_t pgrp, int signum) +KResultOr Process::sys$killpg(pid_t pgrp, int signum) { REQUIRE_PROMISE(proc); if (signum < 1 || signum >= 32) - return -EINVAL; + return EINVAL; if (pgrp < 0) - return -EINVAL; + return EINVAL; return do_killpg(pgrp, signum); } diff --git a/Kernel/Syscalls/link.cpp b/Kernel/Syscalls/link.cpp index f3bf17ff3e..f04e00af4b 100644 --- a/Kernel/Syscalls/link.cpp +++ b/Kernel/Syscalls/link.cpp @@ -30,27 +30,27 @@ namespace Kernel { -int Process::sys$link(Userspace user_params) +KResultOr Process::sys$link(Userspace user_params) { REQUIRE_PROMISE(cpath); Syscall::SC_link_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto old_path = copy_string_from_user(params.old_path); if (old_path.is_null()) - return -EFAULT; + return EFAULT; auto new_path = copy_string_from_user(params.new_path); if (new_path.is_null()) - return -EFAULT; + return EFAULT; return VFS::the().link(old_path, new_path, current_directory()); } -int Process::sys$symlink(Userspace user_params) +KResultOr Process::sys$symlink(Userspace user_params) { REQUIRE_PROMISE(cpath); Syscall::SC_symlink_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto target = get_syscall_path_argument(params.target); if (target.is_error()) return target.error(); diff --git a/Kernel/Syscalls/lseek.cpp b/Kernel/Syscalls/lseek.cpp index a2d55f5f1e..14e2cea1ff 100644 --- a/Kernel/Syscalls/lseek.cpp +++ b/Kernel/Syscalls/lseek.cpp @@ -29,12 +29,12 @@ namespace Kernel { -int Process::sys$lseek(int fd, off_t offset, int whence) +KResultOr Process::sys$lseek(int fd, off_t offset, int whence) { REQUIRE_PROMISE(stdio); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; return description->seek(offset, whence); } diff --git a/Kernel/Syscalls/mkdir.cpp b/Kernel/Syscalls/mkdir.cpp index 870b26c6d8..6ca570d4e5 100644 --- a/Kernel/Syscalls/mkdir.cpp +++ b/Kernel/Syscalls/mkdir.cpp @@ -30,7 +30,7 @@ namespace Kernel { -int Process::sys$mkdir(Userspace user_path, size_t path_length, mode_t mode) +KResultOr Process::sys$mkdir(Userspace user_path, size_t path_length, mode_t mode) { REQUIRE_PROMISE(cpath); auto path = get_syscall_path_argument(user_path, path_length); diff --git a/Kernel/Syscalls/mknod.cpp b/Kernel/Syscalls/mknod.cpp index 1b6a4d9444..393fab4c80 100644 --- a/Kernel/Syscalls/mknod.cpp +++ b/Kernel/Syscalls/mknod.cpp @@ -30,14 +30,14 @@ namespace Kernel { -int Process::sys$mknod(Userspace user_params) +KResultOr Process::sys$mknod(Userspace user_params) { REQUIRE_PROMISE(dpath); Syscall::SC_mknod_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode)) - return -EPERM; + return EPERM; auto path = get_syscall_path_argument(params.path); if (path.is_error()) return path.error(); diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index e194e45c23..8802bd3f72 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -137,13 +137,13 @@ static bool validate_inode_mmap_prot(const Process& process, int prot, const Ino return true; } -FlatPtr Process::sys$mmap(Userspace user_params) +KResultOr Process::sys$mmap(Userspace user_params) { REQUIRE_PROMISE(stdio); Syscall::SC_mmap_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; void* addr = (void*)params.addr; size_t size = params.size; @@ -162,27 +162,27 @@ FlatPtr Process::sys$mmap(Userspace user_params) } if (alignment & ~PAGE_MASK) - return -EINVAL; + return EINVAL; if (page_round_up_would_wrap(size)) - return -EINVAL; + return EINVAL; if (!is_user_range(VirtualAddress(addr), page_round_up(size))) - return -EFAULT; + return EFAULT; String name; if (params.name.characters) { if (params.name.length > PATH_MAX) - return -ENAMETOOLONG; + return ENAMETOOLONG; name = copy_string_from_user(params.name); if (name.is_null()) - return -EFAULT; + return EFAULT; } if (size == 0) - return -EINVAL; + return EINVAL; if ((FlatPtr)addr & ~PAGE_MASK) - return -EINVAL; + return EINVAL; bool map_shared = flags & MAP_SHARED; bool map_anonymous = flags & MAP_ANONYMOUS; @@ -193,19 +193,19 @@ FlatPtr Process::sys$mmap(Userspace user_params) bool map_randomized = flags & MAP_RANDOMIZED; if (map_shared && map_private) - return -EINVAL; + return EINVAL; if (!map_shared && !map_private) - return -EINVAL; + return EINVAL; if (map_fixed && map_randomized) - return -EINVAL; + return EINVAL; if (!validate_mmap_prot(prot, map_stack, map_anonymous)) - return -EINVAL; + return EINVAL; if (map_stack && (!map_private || !map_anonymous)) - return -EINVAL; + return EINVAL; Region* region = nullptr; Optional range; @@ -223,7 +223,7 @@ FlatPtr Process::sys$mmap(Userspace user_params) } if (!range.has_value()) - return -ENOMEM; + return ENOMEM; if (map_anonymous) { auto strategy = map_noreserve ? AllocationStrategy::None : AllocationStrategy::Reserve; @@ -233,24 +233,24 @@ FlatPtr Process::sys$mmap(Userspace user_params) region = region_or_error.value(); } else { if (offset < 0) - return -EINVAL; + return EINVAL; if (static_cast(offset) & ~PAGE_MASK) - return -EINVAL; + return EINVAL; auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; if (description->is_directory()) - return -ENODEV; + return ENODEV; // Require read access even when read protection is not requested. if (!description->is_readable()) - return -EACCES; + return EACCES; if (map_shared) { if ((prot & PROT_WRITE) && !description->is_writable()) - return -EACCES; + return EACCES; } if (description->inode()) { if (!validate_inode_mmap_prot(*this, prot, *description->inode(), map_shared)) - return -EACCES; + return EACCES; } auto region_or_error = description->mmap(*this, range.value(), static_cast(offset), prot, map_shared); @@ -260,7 +260,7 @@ FlatPtr Process::sys$mmap(Userspace user_params) } if (!region) - return -ENOMEM; + return ENOMEM; region->set_mmap(true); if (map_shared) region->set_shared(true); @@ -288,7 +288,7 @@ static KResultOr expand_range_to_page_boundaries(FlatPtr address, size_t return Range { base, end - base.get() }; } -int Process::sys$mprotect(void* addr, size_t size, int prot) +KResultOr Process::sys$mprotect(void* addr, size_t size, int prot) { REQUIRE_PROMISE(stdio); @@ -302,21 +302,21 @@ int Process::sys$mprotect(void* addr, size_t size, int prot) auto range_to_mprotect = range_or_error.value(); if (!range_to_mprotect.size()) - return -EINVAL; + return EINVAL; if (!is_user_range(range_to_mprotect)) - return -EFAULT; + return EFAULT; if (auto* whole_region = space().find_region_from_range(range_to_mprotect)) { if (!whole_region->is_mmap()) - return -EPERM; + return EPERM; if (!validate_mmap_prot(prot, whole_region->is_stack(), whole_region->vmobject().is_anonymous(), whole_region)) - return -EINVAL; + return EINVAL; if (whole_region->access() == prot_to_region_access_flags(prot)) return 0; if (whole_region->vmobject().is_inode() && !validate_inode_mmap_prot(*this, prot, static_cast(whole_region->vmobject()).inode(), whole_region->is_shared())) { - return -EACCES; + return EACCES; } whole_region->set_readable(prot & PROT_READ); whole_region->set_writable(prot & PROT_WRITE); @@ -329,14 +329,14 @@ int Process::sys$mprotect(void* addr, size_t size, int prot) // Check if we can carve out the desired range from an existing region if (auto* old_region = space().find_region_containing(range_to_mprotect)) { if (!old_region->is_mmap()) - return -EPERM; + return EPERM; if (!validate_mmap_prot(prot, old_region->is_stack(), old_region->vmobject().is_anonymous(), old_region)) - return -EINVAL; + return EINVAL; if (old_region->access() == prot_to_region_access_flags(prot)) return 0; if (old_region->vmobject().is_inode() && !validate_inode_mmap_prot(*this, prot, static_cast(old_region->vmobject()).inode(), old_region->is_shared())) { - return -EACCES; + return EACCES; } // This vector is the region(s) adjacent to our range. @@ -363,10 +363,10 @@ int Process::sys$mprotect(void* addr, size_t size, int prot) // FIXME: We should also support mprotect() across multiple regions. (#175) (#964) - return -EINVAL; + return EINVAL; } -int Process::sys$madvise(void* address, size_t size, int advice) +KResultOr Process::sys$madvise(void* address, size_t size, int advice) { REQUIRE_PROMISE(stdio); @@ -377,31 +377,31 @@ int Process::sys$madvise(void* address, size_t size, int advice) auto range_to_madvise = range_or_error.value(); if (!range_to_madvise.size()) - return -EINVAL; + return EINVAL; if (!is_user_range(range_to_madvise)) - return -EFAULT; + return EFAULT; auto* region = space().find_region_from_range(range_to_madvise); if (!region) - return -EINVAL; + return EINVAL; if (!region->is_mmap()) - return -EPERM; + return EPERM; bool set_volatile = advice & MADV_SET_VOLATILE; bool set_nonvolatile = advice & MADV_SET_NONVOLATILE; if (set_volatile && set_nonvolatile) - return -EINVAL; + return EINVAL; if (set_volatile || set_nonvolatile) { if (!region->vmobject().is_anonymous()) - return -EPERM; + return EPERM; bool was_purged = false; switch (region->set_volatile(VirtualAddress(address), size, set_volatile, was_purged)) { case Region::SetVolatileError::Success: break; case Region::SetVolatileError::NotPurgeable: - return -EPERM; + return EPERM; case Region::SetVolatileError::OutOfMemory: - return -ENOMEM; + return ENOMEM; } if (set_nonvolatile) return was_purged ? 1 : 0; @@ -409,26 +409,26 @@ int Process::sys$madvise(void* address, size_t size, int advice) } if (advice & MADV_GET_VOLATILE) { if (!region->vmobject().is_anonymous()) - return -EPERM; + return EPERM; return region->is_volatile(VirtualAddress(address), size) ? 0 : 1; } - return -EINVAL; + return EINVAL; } -int Process::sys$set_mmap_name(Userspace user_params) +KResultOr Process::sys$set_mmap_name(Userspace user_params) { REQUIRE_PROMISE(stdio); Syscall::SC_set_mmap_name_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; if (params.name.length > PATH_MAX) - return -ENAMETOOLONG; + return ENAMETOOLONG; auto name = copy_string_from_user(params.name); if (name.is_null()) - return -EFAULT; + return EFAULT; auto range_or_error = expand_range_to_page_boundaries((FlatPtr)params.addr, params.size); if (range_or_error.is_error()) @@ -438,19 +438,19 @@ int Process::sys$set_mmap_name(Userspaceis_mmap()) - return -EPERM; + return EPERM; region->set_name(move(name)); return 0; } -int Process::sys$munmap(void* addr, size_t size) +KResultOr Process::sys$munmap(void* addr, size_t size) { REQUIRE_PROMISE(stdio); if (!size) - return -EINVAL; + return EINVAL; auto range_or_error = expand_range_to_page_boundaries((FlatPtr)addr, size); if (range_or_error.is_error()) @@ -459,11 +459,11 @@ int Process::sys$munmap(void* addr, size_t size) auto range_to_unmap = range_or_error.value(); if (!is_user_range(range_to_unmap)) - return -EFAULT; + return EFAULT; if (auto* whole_region = space().find_region_from_range(range_to_unmap)) { if (!whole_region->is_mmap()) - return -EPERM; + return EPERM; bool success = space().deallocate_region(*whole_region); VERIFY(success); return 0; @@ -471,7 +471,7 @@ int Process::sys$munmap(void* addr, size_t size) if (auto* old_region = space().find_region_containing(range_to_unmap)) { if (!old_region->is_mmap()) - return -EPERM; + return EPERM; auto new_regions = space().split_region_around_range(*old_region, range_to_unmap); @@ -491,16 +491,16 @@ int Process::sys$munmap(void* addr, size_t size) // FIXME: We should also support munmap() across multiple regions. (#175) - return -EINVAL; + return EINVAL; } -FlatPtr Process::sys$mremap(Userspace user_params) +KResultOr Process::sys$mremap(Userspace user_params) { REQUIRE_PROMISE(stdio); Syscall::SC_mremap_params params {}; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto range_or_error = expand_range_to_page_boundaries((FlatPtr)params.old_address, params.old_size); if (range_or_error.is_error()) @@ -510,10 +510,10 @@ FlatPtr Process::sys$mremap(Userspace user_par auto* old_region = space().find_region_from_range(old_range); if (!old_region) - return -EINVAL; + return EINVAL; if (!old_region->is_mmap()) - return -EPERM; + return EPERM; if (old_region->vmobject().is_shared_inode() && params.flags & MAP_PRIVATE && !(params.flags & (MAP_ANONYMOUS | MAP_NORESERVE))) { auto range = old_region->range(); @@ -536,21 +536,21 @@ FlatPtr Process::sys$mremap(Userspace user_par } dbgln("sys$mremap: Unimplemented remap request (flags={})", params.flags); - return -ENOTIMPL; + return ENOTIMPL; } -FlatPtr Process::sys$allocate_tls(size_t size) +KResultOr Process::sys$allocate_tls(size_t size) { REQUIRE_PROMISE(stdio); if (!size) - return -EINVAL; + return EINVAL; if (!m_master_tls_region.is_null()) - return -EEXIST; + return EEXIST; if (thread_count() != 1) - return -EFAULT; + return EFAULT; Thread* main_thread = nullptr; for_each_thread([&main_thread](auto& thread) { @@ -561,7 +561,7 @@ FlatPtr Process::sys$allocate_tls(size_t size) auto range = space().allocate_range({}, size); if (!range.has_value()) - return -ENOMEM; + return ENOMEM; auto region_or_error = space().allocate_region(range.value(), String(), PROT_READ | PROT_WRITE); if (region_or_error.is_error()) @@ -573,7 +573,7 @@ FlatPtr Process::sys$allocate_tls(size_t size) auto tsr_result = main_thread->make_thread_specific_region({}); if (tsr_result.is_error()) - return -EFAULT; + return EFAULT; auto& tls_descriptor = Processor::current().get_gdt_entry(GDT_SELECTOR_TLS); tls_descriptor.set_base(main_thread->thread_specific_data()); @@ -582,10 +582,10 @@ FlatPtr Process::sys$allocate_tls(size_t size) return m_master_tls_region.unsafe_ptr()->vaddr().get(); } -int Process::sys$msyscall(void* address) +KResultOr Process::sys$msyscall(void* address) { if (space().enforces_syscall_regions()) - return -EPERM; + return EPERM; if (!address) { space().set_enforces_syscall_regions(true); @@ -593,14 +593,14 @@ int Process::sys$msyscall(void* address) } if (!is_user_address(VirtualAddress { address })) - return -EFAULT; + return EFAULT; auto* region = space().find_region_containing(Range { VirtualAddress { address }, 1 }); if (!region) - return -EINVAL; + return EINVAL; if (!region->is_mmap()) - return -EINVAL; + return EINVAL; region->set_syscall_region(true); return 0; diff --git a/Kernel/Syscalls/module.cpp b/Kernel/Syscalls/module.cpp index eae1897d07..77d664aed9 100644 --- a/Kernel/Syscalls/module.cpp +++ b/Kernel/Syscalls/module.cpp @@ -35,10 +35,10 @@ namespace Kernel { extern HashMap>* g_modules; -int Process::sys$module_load(Userspace user_path, size_t path_length) +KResultOr Process::sys$module_load(Userspace user_path, size_t path_length) { if (!is_superuser()) - return -EPERM; + return EPERM; REQUIRE_NO_PROMISES; @@ -59,7 +59,7 @@ int Process::sys$module_load(Userspace user_path, size_t path_lengt auto elf_image = make(storage.data(), storage.size()); if (!elf_image->parse()) - return -ENOEXEC; + return ENOEXEC; HashMap section_storage_by_name; @@ -124,12 +124,12 @@ int Process::sys$module_load(Userspace user_path, size_t path_lengt }); if (missing_symbols) - return -EINVAL; + return EINVAL; auto* text_base = section_storage_by_name.get(".text").value_or(nullptr); if (!text_base) { dbgln("No .text section found in module!"); - return -EINVAL; + return EINVAL; } elf_image->for_each_symbol([&](const ELF::Image::Symbol& symbol) { @@ -147,11 +147,11 @@ int Process::sys$module_load(Userspace user_path, size_t path_lengt }); if (!module->module_init) - return -EINVAL; + return EINVAL; if (g_modules->contains(module->name)) { dbgln("a module with the name {} is already loaded; please unload it first", module->name); - return -EEXIST; + return EEXIST; } module->module_init(); @@ -162,20 +162,20 @@ int Process::sys$module_load(Userspace user_path, size_t path_lengt return 0; } -int Process::sys$module_unload(Userspace user_name, size_t name_length) +KResultOr Process::sys$module_unload(Userspace user_name, size_t name_length) { if (!is_superuser()) - return -EPERM; + return EPERM; REQUIRE_NO_PROMISES; auto module_name = copy_string_from_user(user_name, name_length); if (module_name.is_null()) - return -EFAULT; + return EFAULT; auto it = g_modules->find(module_name); if (it == g_modules->end()) - return -ENOENT; + return ENOENT; if (it->value->module_fini) it->value->module_fini(); diff --git a/Kernel/Syscalls/mount.cpp b/Kernel/Syscalls/mount.cpp index fd265ca20f..7757ddb588 100644 --- a/Kernel/Syscalls/mount.cpp +++ b/Kernel/Syscalls/mount.cpp @@ -36,24 +36,24 @@ namespace Kernel { -int Process::sys$mount(Userspace user_params) +KResultOr Process::sys$mount(Userspace user_params) { if (!is_superuser()) - return -EPERM; + return EPERM; REQUIRE_NO_PROMISES; Syscall::SC_mount_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto source_fd = params.source_fd; auto target = copy_string_from_user(params.target); if (target.is_null()) - return -EFAULT; + return EFAULT; auto fs_type = copy_string_from_user(params.fs_type); if (fs_type.is_null()) - return -EFAULT; + return EFAULT; auto description = file_description(source_fd); if (!description.is_null()) @@ -75,10 +75,10 @@ int Process::sys$mount(Userspace user_params) if (params.flags & MS_BIND) { // We're doing a bind mount. if (description.is_null()) - return -EBADF; + return EBADF; if (!description->custody()) { // We only support bind-mounting inodes, not arbitrary files. - return -ENODEV; + return ENODEV; } return VFS::the().bind_mount(*description->custody(), target_custody, params.flags); } @@ -87,12 +87,12 @@ int Process::sys$mount(Userspace user_params) if (fs_type == "ext2" || fs_type == "Ext2FS") { if (description.is_null()) - return -EBADF; + return EBADF; if (!description->file().is_block_device()) - return -ENOTBLK; + return ENOTBLK; if (!description->file().is_seekable()) { dbgln("mount: this is not a seekable file"); - return -ENODEV; + return ENODEV; } dbgln("mount: attempting to mount {} on {}", description->absolute_path(), target); @@ -100,7 +100,7 @@ int Process::sys$mount(Userspace user_params) fs = Ext2FS::create(*description); } else if (fs_type == "9p" || fs_type == "Plan9FS") { if (description.is_null()) - return -EBADF; + return EBADF; fs = Plan9FS::create(*description); } else if (fs_type == "proc" || fs_type == "ProcFS") { @@ -112,12 +112,12 @@ int Process::sys$mount(Userspace user_params) } else if (fs_type == "tmp" || fs_type == "TmpFS") { fs = TmpFS::create(); } else { - return -ENODEV; + return ENODEV; } if (!fs->initialize()) { dbgln("mount: failed to initialize {} filesystem, fd={}", fs_type, source_fd); - return -ENODEV; + return ENODEV; } auto result = VFS::the().mount(fs.release_nonnull(), target_custody, params.flags); @@ -128,10 +128,10 @@ int Process::sys$mount(Userspace user_params) return result; } -int Process::sys$umount(Userspace user_mountpoint, size_t mountpoint_length) +KResultOr Process::sys$umount(Userspace user_mountpoint, size_t mountpoint_length) { if (!is_superuser()) - return -EPERM; + return EPERM; REQUIRE_NO_PROMISES; diff --git a/Kernel/Syscalls/open.cpp b/Kernel/Syscalls/open.cpp index c84f5231c3..21a01a44ef 100644 --- a/Kernel/Syscalls/open.cpp +++ b/Kernel/Syscalls/open.cpp @@ -32,21 +32,21 @@ namespace Kernel { -int Process::sys$open(Userspace user_params) +KResultOr Process::sys$open(Userspace user_params) { Syscall::SC_open_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; int dirfd = params.dirfd; int options = params.options; u16 mode = params.mode; if (options & O_NOFOLLOW_NOERROR) - return -EINVAL; + return EINVAL; if (options & O_UNLINK_INTERNAL) - return -EINVAL; + return EINVAL; if (options & O_WRONLY) REQUIRE_PROMISE(wpath); @@ -74,11 +74,11 @@ int Process::sys$open(Userspace user_params) } else { auto base_description = file_description(dirfd); if (!base_description) - return -EBADF; + return EBADF; if (!base_description->is_directory()) - return -ENOTDIR; + return ENOTDIR; if (!base_description->custody()) - return -EINVAL; + return EINVAL; base = base_description->custody(); } @@ -88,20 +88,20 @@ int Process::sys$open(Userspace user_params) auto description = result.value(); if (description->inode() && description->inode()->socket()) - return -ENXIO; + return ENXIO; u32 fd_flags = (options & O_CLOEXEC) ? FD_CLOEXEC : 0; m_fds[fd].set(move(description), fd_flags); return fd; } -int Process::sys$close(int fd) +KResultOr Process::sys$close(int fd) { REQUIRE_PROMISE(stdio); auto description = file_description(fd); dbgln_if(IO_DEBUG, "sys$close({}) {}", fd, description.ptr()); if (!description) - return -EBADF; + return EBADF; int rc = description->close(); m_fds[fd] = {}; return rc; diff --git a/Kernel/Syscalls/perf_event.cpp b/Kernel/Syscalls/perf_event.cpp index d7f9ea584a..36229bc232 100644 --- a/Kernel/Syscalls/perf_event.cpp +++ b/Kernel/Syscalls/perf_event.cpp @@ -29,7 +29,7 @@ namespace Kernel { -int Process::sys$perf_event(int type, FlatPtr arg1, FlatPtr arg2) +KResultOr Process::sys$perf_event(int type, FlatPtr arg1, FlatPtr arg2) { return ensure_perf_events().append(type, arg1, arg2); } diff --git a/Kernel/Syscalls/pipe.cpp b/Kernel/Syscalls/pipe.cpp index 5692f2f139..785a4fe9d6 100644 --- a/Kernel/Syscalls/pipe.cpp +++ b/Kernel/Syscalls/pipe.cpp @@ -30,14 +30,14 @@ namespace Kernel { -int Process::sys$pipe(int pipefd[2], int flags) +KResultOr Process::sys$pipe(int pipefd[2], int flags) { REQUIRE_PROMISE(stdio); if (number_of_open_file_descriptors() + 2 > max_open_file_descriptors()) - return -EMFILE; + return EMFILE; // Reject flags other than O_CLOEXEC. if ((flags & O_CLOEXEC) != flags) - return -EINVAL; + return EINVAL; u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0; auto fifo = FIFO::create(m_uid); @@ -53,13 +53,13 @@ int Process::sys$pipe(int pipefd[2], int flags) m_fds[reader_fd].set(open_reader_result.release_value(), fd_flags); m_fds[reader_fd].description()->set_readable(true); if (!copy_to_user(&pipefd[0], &reader_fd)) - return -EFAULT; + return EFAULT; int writer_fd = alloc_fd(); m_fds[writer_fd].set(open_writer_result.release_value(), fd_flags); m_fds[writer_fd].description()->set_writable(true); if (!copy_to_user(&pipefd[1], &writer_fd)) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/pledge.cpp b/Kernel/Syscalls/pledge.cpp index 448fad8ef8..2d1676ab5a 100644 --- a/Kernel/Syscalls/pledge.cpp +++ b/Kernel/Syscalls/pledge.cpp @@ -29,27 +29,27 @@ namespace Kernel { -int Process::sys$pledge(Userspace user_params) +KResultOr Process::sys$pledge(Userspace user_params) { Syscall::SC_pledge_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; if (params.promises.length > 1024 || params.execpromises.length > 1024) - return -E2BIG; + return E2BIG; String promises; if (params.promises.characters) { promises = copy_string_from_user(params.promises); if (promises.is_null()) - return -EFAULT; + return EFAULT; } String execpromises; if (params.execpromises.characters) { execpromises = copy_string_from_user(params.execpromises); if (execpromises.is_null()) - return -EFAULT; + return EFAULT; } auto parse_pledge = [&](auto& pledge_spec, u32& mask) { @@ -70,9 +70,9 @@ int Process::sys$pledge(Userspace user_params) if (!promises.is_null()) { u32 new_promises = 0; if (!parse_pledge(promises, new_promises)) - return -EINVAL; + return EINVAL; if (m_promises && (!new_promises || new_promises & ~m_promises)) - return -EPERM; + return EPERM; m_has_promises = true; m_promises = new_promises; } @@ -80,9 +80,9 @@ int Process::sys$pledge(Userspace user_params) if (!execpromises.is_null()) { u32 new_execpromises = 0; if (!parse_pledge(execpromises, new_execpromises)) - return -EINVAL; + return EINVAL; if (m_execpromises && (!new_execpromises || new_execpromises & ~m_execpromises)) - return -EPERM; + return EPERM; m_has_execpromises = true; m_execpromises = new_execpromises; } diff --git a/Kernel/Syscalls/prctl.cpp b/Kernel/Syscalls/prctl.cpp index f5d06ea135..05dd95f102 100644 --- a/Kernel/Syscalls/prctl.cpp +++ b/Kernel/Syscalls/prctl.cpp @@ -29,7 +29,7 @@ namespace Kernel { -int Process::sys$prctl(int option, FlatPtr arg1, [[maybe_unused]] FlatPtr arg2) +KResultOr Process::sys$prctl(int option, FlatPtr arg1, [[maybe_unused]] FlatPtr arg2) { switch (option) { case PR_GET_DUMPABLE: @@ -38,7 +38,7 @@ int Process::sys$prctl(int option, FlatPtr arg1, [[maybe_unused]] FlatPtr arg2) set_dumpable(arg1); return 0; default: - return -EINVAL; + return EINVAL; } return 0; } diff --git a/Kernel/Syscalls/process.cpp b/Kernel/Syscalls/process.cpp index 64f487d79b..e604a1e161 100644 --- a/Kernel/Syscalls/process.cpp +++ b/Kernel/Syscalls/process.cpp @@ -29,61 +29,61 @@ namespace Kernel { -pid_t Process::sys$getpid() +KResultOr Process::sys$getpid() { REQUIRE_PROMISE(stdio); return m_pid.value(); } -pid_t Process::sys$getppid() +KResultOr Process::sys$getppid() { REQUIRE_PROMISE(stdio); return m_ppid.value(); } -int Process::sys$get_process_name(Userspace buffer, size_t buffer_size) +KResultOr Process::sys$get_process_name(Userspace buffer, size_t buffer_size) { REQUIRE_PROMISE(stdio); if (m_name.length() + 1 > buffer_size) - return -ENAMETOOLONG; + return ENAMETOOLONG; if (!copy_to_user(buffer, m_name.characters(), m_name.length() + 1)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$set_process_name(Userspace user_name, size_t user_name_length) +KResultOr Process::sys$set_process_name(Userspace user_name, size_t user_name_length) { REQUIRE_PROMISE(proc); if (user_name_length > 256) - return -ENAMETOOLONG; + return ENAMETOOLONG; auto name = copy_string_from_user(user_name, user_name_length); if (name.is_null()) - return -EFAULT; + return EFAULT; // Empty and whitespace-only names only exist to confuse users. if (name.is_whitespace()) - return -EINVAL; + return EINVAL; m_name = move(name); return 0; } -int Process::sys$set_coredump_metadata(Userspace user_params) +KResultOr Process::sys$set_coredump_metadata(Userspace user_params) { Syscall::SC_set_coredump_metadata_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; if (params.key.length == 0 || params.key.length > 16 * KiB) - return -EINVAL; + return EINVAL; if (params.value.length > 16 * KiB) - return -EINVAL; + return EINVAL; auto copied_key = copy_string_from_user(params.key.characters, params.key.length); if (copied_key.is_null()) - return -EFAULT; + return EFAULT; auto copied_value = copy_string_from_user(params.value.characters, params.value.length); if (copied_value.is_null()) - return -EFAULT; + return EFAULT; if (!m_coredump_metadata.contains(copied_key) && m_coredump_metadata.size() >= 16) - return -EFAULT; + return EFAULT; m_coredump_metadata.set(move(copied_key), move(copied_value)); return 0; } diff --git a/Kernel/Syscalls/profiling.cpp b/Kernel/Syscalls/profiling.cpp index 679a76e422..c02cf73215 100644 --- a/Kernel/Syscalls/profiling.cpp +++ b/Kernel/Syscalls/profiling.cpp @@ -32,32 +32,32 @@ namespace Kernel { -int Process::sys$profiling_enable(pid_t pid) +KResultOr Process::sys$profiling_enable(pid_t pid) { REQUIRE_NO_PROMISES; ScopedSpinLock lock(g_processes_lock); auto process = Process::from_pid(pid); if (!process) - return -ESRCH; + return ESRCH; if (process->is_dead()) - return -ESRCH; + return ESRCH; if (!is_superuser() && process->uid() != m_euid) - return -EPERM; + return EPERM; process->ensure_perf_events(); process->set_profiling(true); return 0; } -int Process::sys$profiling_disable(pid_t pid) +KResultOr Process::sys$profiling_disable(pid_t pid) { ScopedSpinLock lock(g_processes_lock); auto process = Process::from_pid(pid); if (!process) - return -ESRCH; + return ESRCH; if (!is_superuser() && process->uid() != m_euid) - return -EPERM; + return EPERM; if (!process->is_profiling()) - return -EINVAL; + return EINVAL; process->set_profiling(false); return 0; } diff --git a/Kernel/Syscalls/ptrace.cpp b/Kernel/Syscalls/ptrace.cpp index e882b02dcd..922f96c299 100644 --- a/Kernel/Syscalls/ptrace.cpp +++ b/Kernel/Syscalls/ptrace.cpp @@ -160,12 +160,12 @@ static KResultOr handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par return KSuccess; } -int Process::sys$ptrace(Userspace user_params) +KResultOr Process::sys$ptrace(Userspace user_params) { REQUIRE_PROMISE(ptrace); Syscall::SC_ptrace_params params {}; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto result = handle_ptrace(params, *this); return result.is_error() ? result.error().error() : result.value(); } diff --git a/Kernel/Syscalls/purge.cpp b/Kernel/Syscalls/purge.cpp index 582fb4c016..f1164a8d7e 100644 --- a/Kernel/Syscalls/purge.cpp +++ b/Kernel/Syscalls/purge.cpp @@ -32,11 +32,11 @@ namespace Kernel { -int Process::sys$purge(int mode) +KResultOr Process::sys$purge(int mode) { REQUIRE_NO_PROMISES; if (!is_superuser()) - return -EPERM; + return EPERM; int purged_page_count = 0; if (mode & PURGE_ALL_VOLATILE) { NonnullRefPtrVector vmobjects; diff --git a/Kernel/Syscalls/read.cpp b/Kernel/Syscalls/read.cpp index 801e84d250..8455984372 100644 --- a/Kernel/Syscalls/read.cpp +++ b/Kernel/Syscalls/read.cpp @@ -30,36 +30,36 @@ namespace Kernel { -ssize_t Process::sys$readv(int fd, Userspace iov, int iov_count) +KResultOr Process::sys$readv(int fd, Userspace iov, int iov_count) { REQUIRE_PROMISE(stdio); if (iov_count < 0) - return -EINVAL; + return EINVAL; // Arbitrary pain threshold. if (iov_count > (int)MiB) - return -EFAULT; + return EFAULT; u64 total_length = 0; Vector vecs; vecs.resize(iov_count); if (!copy_n_from_user(vecs.data(), iov, iov_count)) - return -EFAULT; + return EFAULT; for (auto& vec : vecs) { total_length += vec.iov_len; if (total_length > NumericLimits::max()) - return -EINVAL; + return EINVAL; } auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; if (!description->is_readable()) - return -EBADF; + return EBADF; if (description->is_directory()) - return -EISDIR; + return EISDIR; int nread = 0; for (auto& vec : vecs) { @@ -67,15 +67,15 @@ ssize_t Process::sys$readv(int fd, Userspace iov, int iov_c if (!description->can_read()) { auto unblock_flags = Thread::FileBlocker::BlockFlags::None; if (Thread::current()->block({}, *description, unblock_flags).was_interrupted()) - return -EINTR; + return EINTR; if (!((u32)unblock_flags & (u32)Thread::FileBlocker::BlockFlags::Read)) - return -EAGAIN; + return EAGAIN; // TODO: handle exceptions in unblock_flags } } auto buffer = UserOrKernelBuffer::for_user_buffer((u8*)vec.iov_base, vec.iov_len); if (!buffer.has_value()) - return -EFAULT; + return EFAULT; auto result = description->read(buffer.value(), vec.iov_len); if (result.is_error()) return result.error(); @@ -85,34 +85,34 @@ ssize_t Process::sys$readv(int fd, Userspace iov, int iov_c return nread; } -ssize_t Process::sys$read(int fd, Userspace buffer, ssize_t size) +KResultOr Process::sys$read(int fd, Userspace buffer, ssize_t size) { REQUIRE_PROMISE(stdio); if (size < 0) - return -EINVAL; + return EINVAL; if (size == 0) return 0; dbgln_if(IO_DEBUG, "sys$read({}, {}, {})", fd, buffer.ptr(), size); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; if (!description->is_readable()) - return -EBADF; + return EBADF; if (description->is_directory()) - return -EISDIR; + return EISDIR; if (description->is_blocking()) { if (!description->can_read()) { auto unblock_flags = Thread::FileBlocker::BlockFlags::None; if (Thread::current()->block({}, *description, unblock_flags).was_interrupted()) - return -EINTR; + return EINTR; if (!((u32)unblock_flags & (u32)Thread::FileBlocker::BlockFlags::Read)) - return -EAGAIN; + return EAGAIN; // TODO: handle exceptions in unblock_flags } } auto user_buffer = UserOrKernelBuffer::for_user_buffer(buffer, size); if (!user_buffer.has_value()) - return -EFAULT; + return EFAULT; auto result = description->read(user_buffer.value(), size); if (result.is_error()) return result.error(); diff --git a/Kernel/Syscalls/readlink.cpp b/Kernel/Syscalls/readlink.cpp index 7c4b92a391..9c0cfa205c 100644 --- a/Kernel/Syscalls/readlink.cpp +++ b/Kernel/Syscalls/readlink.cpp @@ -31,13 +31,13 @@ namespace Kernel { -int Process::sys$readlink(Userspace user_params) +KResultOr Process::sys$readlink(Userspace user_params) { REQUIRE_PROMISE(rpath); Syscall::SC_readlink_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto path = get_syscall_path_argument(params.path); if (path.is_error()) @@ -49,7 +49,7 @@ int Process::sys$readlink(Userspace user_par auto description = result.value(); if (!description->metadata().is_symlink()) - return -EINVAL; + return EINVAL; auto contents = description->read_entire_file(); if (contents.is_error()) @@ -58,7 +58,7 @@ int Process::sys$readlink(Userspace user_par auto& link_target = *contents.value(); auto size_to_copy = min(link_target.size(), params.buffer.size); if (!copy_to_user(params.buffer.data, link_target.data(), size_to_copy)) - return -EFAULT; + return EFAULT; // Note: we return the whole size here, not the copied size. return link_target.size(); } diff --git a/Kernel/Syscalls/realpath.cpp b/Kernel/Syscalls/realpath.cpp index 93a3dea706..e556fafc14 100644 --- a/Kernel/Syscalls/realpath.cpp +++ b/Kernel/Syscalls/realpath.cpp @@ -31,13 +31,13 @@ namespace Kernel { -int Process::sys$realpath(Userspace user_params) +KResultOr Process::sys$realpath(Userspace user_params) { REQUIRE_PROMISE(rpath); Syscall::SC_realpath_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto path = get_syscall_path_argument(params.path); if (path.is_error()) @@ -52,7 +52,7 @@ int Process::sys$realpath(Userspace user_par size_t ideal_size = absolute_path.length() + 1; auto size_to_copy = min(ideal_size, params.buffer.size); if (!copy_to_user(params.buffer.data, absolute_path.characters(), size_to_copy)) - return -EFAULT; + return EFAULT; // Note: we return the whole size here, not the copied size. return ideal_size; }; diff --git a/Kernel/Syscalls/rename.cpp b/Kernel/Syscalls/rename.cpp index ef9463c860..e457d3891e 100644 --- a/Kernel/Syscalls/rename.cpp +++ b/Kernel/Syscalls/rename.cpp @@ -30,12 +30,12 @@ namespace Kernel { -int Process::sys$rename(Userspace user_params) +KResultOr Process::sys$rename(Userspace user_params) { REQUIRE_PROMISE(cpath); Syscall::SC_rename_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto old_path = get_syscall_path_argument(params.old_path); if (old_path.is_error()) return old_path.error(); diff --git a/Kernel/Syscalls/rmdir.cpp b/Kernel/Syscalls/rmdir.cpp index 56da04f8ff..c5959d09ea 100644 --- a/Kernel/Syscalls/rmdir.cpp +++ b/Kernel/Syscalls/rmdir.cpp @@ -30,7 +30,7 @@ namespace Kernel { -int Process::sys$rmdir(Userspace user_path, size_t path_length) +KResultOr Process::sys$rmdir(Userspace user_path, size_t path_length) { REQUIRE_PROMISE(cpath); auto path = get_syscall_path_argument(user_path, path_length); diff --git a/Kernel/Syscalls/sched.cpp b/Kernel/Syscalls/sched.cpp index 12c16f7f92..48a1faadbd 100644 --- a/Kernel/Syscalls/sched.cpp +++ b/Kernel/Syscalls/sched.cpp @@ -28,36 +28,36 @@ namespace Kernel { -int Process::sys$yield() +KResultOr Process::sys$yield() { REQUIRE_PROMISE(stdio); Thread::current()->yield_without_holding_big_lock(); return 0; } -int Process::sys$donate(pid_t tid) +KResultOr Process::sys$donate(pid_t tid) { REQUIRE_PROMISE(stdio); if (tid < 0) - return -EINVAL; + return EINVAL; ScopedCritical critical; auto thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) - return -ESRCH; + return ESRCH; Thread::current()->donate_without_holding_big_lock(thread, "sys$donate"); return 0; } -int Process::sys$sched_setparam(int pid, Userspace user_param) +KResultOr Process::sys$sched_setparam(int pid, Userspace user_param) { REQUIRE_PROMISE(proc); struct sched_param desired_param; if (!copy_from_user(&desired_param, user_param)) - return -EFAULT; + return EFAULT; if (desired_param.sched_priority < THREAD_PRIORITY_MIN || desired_param.sched_priority > THREAD_PRIORITY_MAX) - return -EINVAL; + return EINVAL; auto* peer = Thread::current(); ScopedSpinLock lock(g_scheduler_lock); @@ -65,16 +65,16 @@ int Process::sys$sched_setparam(int pid, Userspace us peer = Thread::from_tid(pid); if (!peer) - return -ESRCH; + return ESRCH; if (!is_superuser() && m_euid != peer->process().m_uid && m_uid != peer->process().m_uid) - return -EPERM; + return EPERM; peer->set_priority((u32)desired_param.sched_priority); return 0; } -int Process::sys$sched_getparam(pid_t pid, Userspace user_param) +KResultOr Process::sys$sched_getparam(pid_t pid, Userspace user_param) { REQUIRE_PROMISE(proc); int priority; @@ -88,10 +88,10 @@ int Process::sys$sched_getparam(pid_t pid, Userspace user_p } if (!peer) - return -ESRCH; + return ESRCH; if (!is_superuser() && m_euid != peer->process().m_uid && m_uid != peer->process().m_uid) - return -EPERM; + return EPERM; priority = (int)peer->priority(); } @@ -100,7 +100,7 @@ int Process::sys$sched_getparam(pid_t pid, Userspace user_p priority }; if (!copy_to_user(user_param, ¶m)) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/select.cpp b/Kernel/Syscalls/select.cpp index 0009fdf37f..4076a871d0 100644 --- a/Kernel/Syscalls/select.cpp +++ b/Kernel/Syscalls/select.cpp @@ -32,22 +32,22 @@ namespace Kernel { -int Process::sys$select(const Syscall::SC_select_params* user_params) +KResultOr Process::sys$select(const Syscall::SC_select_params* user_params) { REQUIRE_PROMISE(stdio); Syscall::SC_select_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; if (params.nfds < 0) - return -EINVAL; + return EINVAL; Thread::BlockTimeout timeout; if (params.timeout) { timespec timeout_copy; if (!copy_from_user(&timeout_copy, params.timeout)) - return -EFAULT; + return EFAULT; timeout = Thread::BlockTimeout(false, &timeout_copy); } @@ -57,7 +57,7 @@ int Process::sys$select(const Syscall::SC_select_params* user_params) if (params.sigmask) { sigset_t sigmask_copy; if (!copy_from_user(&sigmask_copy, params.sigmask)) - return -EFAULT; + return EFAULT; previous_signal_mask = current_thread->update_signal_mask(sigmask_copy); } ScopeGuard rollback_signal_mask([&]() { @@ -67,11 +67,11 @@ int Process::sys$select(const Syscall::SC_select_params* user_params) fd_set fds_read, fds_write, fds_except; if (params.readfds && !copy_from_user(&fds_read, params.readfds)) - return -EFAULT; + return EFAULT; if (params.writefds && !copy_from_user(&fds_write, params.writefds)) - return -EFAULT; + return EFAULT; if (params.exceptfds && !copy_from_user(&fds_except, params.exceptfds)) - return -EFAULT; + return EFAULT; Thread::SelectBlocker::FDVector fds_info; Vector fds; @@ -89,7 +89,7 @@ int Process::sys$select(const Syscall::SC_select_params* user_params) auto description = file_description(fd); if (!description) { dbgln("sys$select: Bad fd number {}", fd); - return -EBADF; + return EBADF; } fds_info.append({ description.release_nonnull(), (Thread::FileBlocker::BlockFlags)block_flags }); fds.append(fd); @@ -100,7 +100,7 @@ int Process::sys$select(const Syscall::SC_select_params* user_params) if (current_thread->block(timeout, fds_info).was_interrupted()) { dbgln_if(POLL_SELECT_DEBUG, "select was interrupted"); - return -EINTR; + return EINTR; } if (params.readfds) @@ -130,47 +130,47 @@ int Process::sys$select(const Syscall::SC_select_params* user_params) } if (params.readfds && !copy_to_user(params.readfds, &fds_read)) - return -EFAULT; + return EFAULT; if (params.writefds && !copy_to_user(params.writefds, &fds_write)) - return -EFAULT; + return EFAULT; if (params.exceptfds && !copy_to_user(params.exceptfds, &fds_except)) - return -EFAULT; + return EFAULT; return marked_fd_count; } -int Process::sys$poll(Userspace user_params) +KResultOr Process::sys$poll(Userspace user_params) { REQUIRE_PROMISE(stdio); // FIXME: Return -EINVAL if timeout is invalid. Syscall::SC_poll_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; if (params.nfds >= m_max_open_file_descriptors) - return -ENOBUFS; + return ENOBUFS; Thread::BlockTimeout timeout; if (params.timeout) { timespec timeout_copy; if (!copy_from_user(&timeout_copy, params.timeout)) - return -EFAULT; + return EFAULT; timeout = Thread::BlockTimeout(false, &timeout_copy); } sigset_t sigmask = {}; if (params.sigmask && !copy_from_user(&sigmask, params.sigmask)) - return -EFAULT; + return EFAULT; Vector fds_copy; if (params.nfds > 0) { Checked nfds_checked = sizeof(pollfd); nfds_checked *= params.nfds; if (nfds_checked.has_overflow()) - return -EFAULT; + return EFAULT; fds_copy.resize(params.nfds); if (!copy_from_user(fds_copy.data(), ¶ms.fds[0], nfds_checked.value())) - return -EFAULT; + return EFAULT; } Thread::SelectBlocker::FDVector fds_info; @@ -179,7 +179,7 @@ int Process::sys$poll(Userspace user_params) auto description = file_description(pfd.fd); if (!description) { dbgln("sys$poll: Bad fd number {}", pfd.fd); - return -EBADF; + return EBADF; } u32 block_flags = (u32)Thread::FileBlocker::BlockFlags::Exception; // always want POLLERR, POLLHUP, POLLNVAL if (pfd.events & POLLIN) @@ -205,7 +205,7 @@ int Process::sys$poll(Userspace user_params) dbgln("polling on {} fds, timeout={}", fds_info.size(), params.timeout); if (current_thread->block(timeout, fds_info).was_interrupted()) - return -EINTR; + return EINTR; int fds_with_revents = 0; @@ -243,7 +243,7 @@ int Process::sys$poll(Userspace user_params) } if (params.nfds > 0 && !copy_to_user(¶ms.fds[0], fds_copy.data(), params.nfds * sizeof(pollfd))) - return -EFAULT; + return EFAULT; return fds_with_revents; } diff --git a/Kernel/Syscalls/sendfd.cpp b/Kernel/Syscalls/sendfd.cpp index 66f6b4d654..d1ab07c46e 100644 --- a/Kernel/Syscalls/sendfd.cpp +++ b/Kernel/Syscalls/sendfd.cpp @@ -30,39 +30,39 @@ namespace Kernel { -int Process::sys$sendfd(int sockfd, int fd) +KResultOr Process::sys$sendfd(int sockfd, int fd) { REQUIRE_PROMISE(sendfd); auto socket_description = file_description(sockfd); if (!socket_description) - return -EBADF; + return EBADF; if (!socket_description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *socket_description->socket(); if (!socket.is_local()) - return -EAFNOSUPPORT; + return EAFNOSUPPORT; if (!socket.is_connected()) - return -ENOTCONN; + return ENOTCONN; auto passing_descriptor = file_description(fd); if (!passing_descriptor) - return -EBADF; + return EBADF; auto& local_socket = static_cast(socket); return local_socket.sendfd(*socket_description, *passing_descriptor); } -int Process::sys$recvfd(int sockfd, int options) +KResultOr Process::sys$recvfd(int sockfd, int options) { REQUIRE_PROMISE(recvfd); auto socket_description = file_description(sockfd); if (!socket_description) - return -EBADF; + return EBADF; if (!socket_description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *socket_description->socket(); if (!socket.is_local()) - return -EAFNOSUPPORT; + return EAFNOSUPPORT; int new_fd = alloc_fd(); if (new_fd < 0) diff --git a/Kernel/Syscalls/setpgid.cpp b/Kernel/Syscalls/setpgid.cpp index fb650ecf23..f66629b004 100644 --- a/Kernel/Syscalls/setpgid.cpp +++ b/Kernel/Syscalls/setpgid.cpp @@ -29,7 +29,7 @@ namespace Kernel { -pid_t Process::sys$getsid(pid_t pid) +KResultOr Process::sys$getsid(pid_t pid) { REQUIRE_PROMISE(proc); if (pid == 0) @@ -37,13 +37,13 @@ pid_t Process::sys$getsid(pid_t pid) ScopedSpinLock lock(g_processes_lock); auto process = Process::from_pid(pid); if (!process) - return -ESRCH; + return ESRCH; if (m_sid != process->m_sid) - return -EPERM; + return EPERM; return process->m_sid.value(); } -pid_t Process::sys$setsid() +KResultOr Process::sys$setsid() { REQUIRE_PROMISE(proc); InterruptDisabler disabler; @@ -53,7 +53,7 @@ pid_t Process::sys$setsid() return IterationDecision::Break; }); if (found_process_with_same_pgid_as_my_pid) - return -EPERM; + return EPERM; // Create a new Session and a new ProcessGroup. m_sid = m_pid.value(); m_pg = ProcessGroup::create(ProcessGroupID(m_pid.value())); @@ -61,7 +61,7 @@ pid_t Process::sys$setsid() return m_sid.value(); } -pid_t Process::sys$getpgid(pid_t pid) +KResultOr Process::sys$getpgid(pid_t pid) { REQUIRE_PROMISE(proc); if (pid == 0) @@ -69,11 +69,11 @@ pid_t Process::sys$getpgid(pid_t pid) ScopedSpinLock lock(g_processes_lock); // FIXME: Use a ProcessHandle auto process = Process::from_pid(pid); if (!process) - return -ESRCH; + return ESRCH; return process->pgid().value(); } -pid_t Process::sys$getpgrp() +KResultOr Process::sys$getpgrp() { REQUIRE_PROMISE(stdio); return pgid().value(); @@ -93,32 +93,32 @@ SessionID Process::get_sid_from_pgid(ProcessGroupID pgid) return sid; } -int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid) +KResultOr Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid) { REQUIRE_PROMISE(proc); ScopedSpinLock lock(g_processes_lock); // FIXME: Use a ProcessHandle ProcessID pid = specified_pid ? ProcessID(specified_pid) : m_pid; if (specified_pgid < 0) { // The value of the pgid argument is less than 0, or is not a value supported by the implementation. - return -EINVAL; + return EINVAL; } auto process = Process::from_pid(pid); if (!process) - return -ESRCH; + return ESRCH; if (process != this && process->ppid() != m_pid) { // The value of the pid argument does not match the process ID // of the calling process or of a child process of the calling process. - return -ESRCH; + return ESRCH; } if (process->is_session_leader()) { // The process indicated by the pid argument is a session leader. - return -EPERM; + return EPERM; } if (process->ppid() == m_pid && process->sid() != sid()) { // The value of the pid argument matches the process ID of a child // process of the calling process and the child process is not in // the same session as the calling process. - return -EPERM; + return EPERM; } ProcessGroupID new_pgid = specified_pgid ? ProcessGroupID(specified_pgid) : process->m_pid.value(); @@ -126,12 +126,12 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid) SessionID new_sid = get_sid_from_pgid(new_pgid); if (new_sid != -1 && current_sid != new_sid) { // Can't move a process between sessions. - return -EPERM; + return EPERM; } if (new_sid == -1 && new_pgid != process->m_pid.value()) { // The value of the pgid argument is valid, but is not // the calling pid, and is not an existing process group. - return -EPERM; + return EPERM; } // FIXME: There are more EPERM conditions to check for here.. process->m_pg = ProcessGroup::find_or_create(new_pgid); diff --git a/Kernel/Syscalls/setuid.cpp b/Kernel/Syscalls/setuid.cpp index 9e63ceb6bd..7426e6cf15 100644 --- a/Kernel/Syscalls/setuid.cpp +++ b/Kernel/Syscalls/setuid.cpp @@ -28,12 +28,12 @@ namespace Kernel { -int Process::sys$seteuid(uid_t euid) +KResultOr Process::sys$seteuid(uid_t euid) { REQUIRE_PROMISE(id); if (euid != m_uid && euid != m_suid && !is_superuser()) - return -EPERM; + return EPERM; if (m_euid != euid) set_dumpable(false); @@ -41,12 +41,12 @@ int Process::sys$seteuid(uid_t euid) return 0; } -int Process::sys$setegid(gid_t egid) +KResultOr Process::sys$setegid(gid_t egid) { REQUIRE_PROMISE(id); if (egid != m_gid && egid != m_sgid && !is_superuser()) - return -EPERM; + return EPERM; if (m_egid != egid) set_dumpable(false); @@ -55,12 +55,12 @@ int Process::sys$setegid(gid_t egid) return 0; } -int Process::sys$setuid(uid_t uid) +KResultOr Process::sys$setuid(uid_t uid) { REQUIRE_PROMISE(id); if (uid != m_uid && uid != m_euid && !is_superuser()) - return -EPERM; + return EPERM; if (m_euid != uid) set_dumpable(false); @@ -71,12 +71,12 @@ int Process::sys$setuid(uid_t uid) return 0; } -int Process::sys$setgid(gid_t gid) +KResultOr Process::sys$setgid(gid_t gid) { REQUIRE_PROMISE(id); if (gid != m_gid && gid != m_egid && !is_superuser()) - return -EPERM; + return EPERM; if (m_egid != gid) set_dumpable(false); @@ -87,7 +87,7 @@ int Process::sys$setgid(gid_t gid) return 0; } -int Process::sys$setresuid(uid_t ruid, uid_t euid, uid_t suid) +KResultOr Process::sys$setresuid(uid_t ruid, uid_t euid, uid_t suid) { REQUIRE_PROMISE(id); @@ -100,7 +100,7 @@ int Process::sys$setresuid(uid_t ruid, uid_t euid, uid_t suid) auto ok = [this](uid_t id) { return id == m_uid || id == m_euid || id == m_suid; }; if ((!ok(ruid) || !ok(euid) || !ok(suid)) && !is_superuser()) - return -EPERM; + return EPERM; if (m_euid != euid) set_dumpable(false); @@ -111,7 +111,7 @@ int Process::sys$setresuid(uid_t ruid, uid_t euid, uid_t suid) return 0; } -int Process::sys$setresgid(gid_t rgid, gid_t egid, gid_t sgid) +KResultOr Process::sys$setresgid(gid_t rgid, gid_t egid, gid_t sgid) { REQUIRE_PROMISE(id); @@ -124,7 +124,7 @@ int Process::sys$setresgid(gid_t rgid, gid_t egid, gid_t sgid) auto ok = [this](gid_t id) { return id == m_gid || id == m_egid || id == m_sgid; }; if ((!ok(rgid) || !ok(egid) || !ok(sgid)) && !is_superuser()) - return -EPERM; + return EPERM; if (m_egid != egid) set_dumpable(false); @@ -135,13 +135,13 @@ int Process::sys$setresgid(gid_t rgid, gid_t egid, gid_t sgid) return 0; } -int Process::sys$setgroups(ssize_t count, Userspace user_gids) +KResultOr Process::sys$setgroups(ssize_t count, Userspace user_gids) { REQUIRE_PROMISE(id); if (count < 0) - return -EINVAL; + return EINVAL; if (!is_superuser()) - return -EPERM; + return EPERM; if (!count) { m_extra_gids.clear(); @@ -151,7 +151,7 @@ int Process::sys$setgroups(ssize_t count, Userspace user_gids) Vector gids; gids.resize(count); if (!copy_n_from_user(gids.data(), user_gids, count)) - return -EFAULT; + return EFAULT; HashTable unique_extra_gids; for (auto& gid : gids) { diff --git a/Kernel/Syscalls/shutdown.cpp b/Kernel/Syscalls/shutdown.cpp index 52d43c180e..16eb12e5a8 100644 --- a/Kernel/Syscalls/shutdown.cpp +++ b/Kernel/Syscalls/shutdown.cpp @@ -31,10 +31,10 @@ namespace Kernel { -int Process::sys$reboot() +KResultOr Process::sys$reboot() { if (!is_superuser()) - return -EPERM; + return EPERM; REQUIRE_NO_PROMISES; @@ -51,10 +51,10 @@ int Process::sys$reboot() return 0; } -int Process::sys$halt() +KResultOr Process::sys$halt() { if (!is_superuser()) - return -EPERM; + return EPERM; REQUIRE_NO_PROMISES; diff --git a/Kernel/Syscalls/sigaction.cpp b/Kernel/Syscalls/sigaction.cpp index f89eb775a1..dcd875d087 100644 --- a/Kernel/Syscalls/sigaction.cpp +++ b/Kernel/Syscalls/sigaction.cpp @@ -30,7 +30,7 @@ namespace Kernel { -int Process::sys$sigprocmask(int how, Userspace set, Userspace old_set) +KResultOr Process::sys$sigprocmask(int how, Userspace set, Userspace old_set) { REQUIRE_PROMISE(sigaction); auto current_thread = Thread::current(); @@ -38,7 +38,7 @@ int Process::sys$sigprocmask(int how, Userspace set, Userspace< if (set) { sigset_t set_value; if (!copy_from_user(&set_value, set)) - return -EFAULT; + return EFAULT; switch (how) { case SIG_BLOCK: previous_signal_mask = current_thread->signal_mask_block(set_value, true); @@ -50,46 +50,46 @@ int Process::sys$sigprocmask(int how, Userspace set, Userspace< previous_signal_mask = current_thread->update_signal_mask(set_value); break; default: - return -EINVAL; + return EINVAL; } } else { previous_signal_mask = current_thread->signal_mask(); } if (old_set && !copy_to_user(old_set, &previous_signal_mask)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$sigpending(Userspace set) +KResultOr Process::sys$sigpending(Userspace set) { REQUIRE_PROMISE(stdio); auto pending_signals = Thread::current()->pending_signals(); if (!copy_to_user(set, &pending_signals)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$sigaction(int signum, const sigaction* act, sigaction* old_act) +KResultOr Process::sys$sigaction(int signum, const sigaction* act, sigaction* old_act) { REQUIRE_PROMISE(sigaction); if (signum < 1 || signum >= 32 || signum == SIGKILL || signum == SIGSTOP) - return -EINVAL; + return EINVAL; InterruptDisabler disabler; // FIXME: This should use a narrower lock. Maybe a way to ignore signals temporarily? auto& action = Thread::current()->m_signal_action_data[signum]; if (old_act) { if (!copy_to_user(&old_act->sa_flags, &action.flags)) - return -EFAULT; + return EFAULT; if (!copy_to_user(&old_act->sa_sigaction, &action.handler_or_sigaction, sizeof(action.handler_or_sigaction))) - return -EFAULT; + return EFAULT; } if (!copy_from_user(&action.flags, &act->sa_flags)) - return -EFAULT; + return EFAULT; if (!copy_from_user(&action.handler_or_sigaction, &act->sa_sigaction, sizeof(action.handler_or_sigaction))) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$sigreturn([[maybe_unused]] RegisterState& registers) +KResultOr Process::sys$sigreturn([[maybe_unused]] RegisterState& registers) { REQUIRE_PROMISE(stdio); SmapDisabler disabler; diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp index 6529edef43..a68b930783 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -40,12 +40,12 @@ namespace Kernel { REQUIRE_PROMISE(unix); \ } while (0) -int Process::sys$socket(int domain, int type, int protocol) +KResultOr Process::sys$socket(int domain, int type, int protocol) { REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain); if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser()) - return -EACCES; + return EACCES; int fd = alloc_fd(); if (fd < 0) return fd; @@ -66,59 +66,59 @@ int Process::sys$socket(int domain, int type, int protocol) return fd; } -int Process::sys$bind(int sockfd, Userspace address, socklen_t address_length) +KResultOr Process::sys$bind(int sockfd, Userspace address, socklen_t address_length) { auto description = file_description(sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); return socket.bind(address, address_length); } -int Process::sys$listen(int sockfd, int backlog) +KResultOr Process::sys$listen(int sockfd, int backlog) { if (backlog < 0) - return -EINVAL; + return EINVAL; auto description = file_description(sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); if (socket.is_connected()) - return -EINVAL; + return EINVAL; return socket.listen(backlog); } -int Process::sys$accept(int accepting_socket_fd, Userspace user_address, Userspace user_address_size) +KResultOr Process::sys$accept(int accepting_socket_fd, Userspace user_address, Userspace user_address_size) { REQUIRE_PROMISE(accept); socklen_t address_size = 0; if (user_address && !copy_from_user(&address_size, static_ptr_cast(user_address_size))) - return -EFAULT; + return EFAULT; int accepted_socket_fd = alloc_fd(); if (accepted_socket_fd < 0) return accepted_socket_fd; auto accepting_socket_description = file_description(accepting_socket_fd); if (!accepting_socket_description) - return -EBADF; + return EBADF; if (!accepting_socket_description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *accepting_socket_description->socket(); if (!socket.can_accept()) { if (accepting_socket_description->is_blocking()) { auto unblock_flags = Thread::FileBlocker::BlockFlags::None; if (Thread::current()->block({}, *accepting_socket_description, unblock_flags).was_interrupted()) - return -EINTR; + return EINTR; } else { - return -EAGAIN; + return EAGAIN; } } auto accepted_socket = socket.accept(); @@ -129,9 +129,9 @@ int Process::sys$accept(int accepting_socket_fd, Userspace user_addre address_size = min(sizeof(sockaddr_un), static_cast(address_size)); accepted_socket->get_peer_address((sockaddr*)address_buffer, &address_size); if (!copy_to_user(user_address, address_buffer, address_size)) - return -EFAULT; + return EFAULT; if (!copy_to_user(user_address_size, &address_size)) - return -EFAULT; + return EFAULT; } auto accepted_socket_description_result = FileDescription::create(*accepted_socket); @@ -150,16 +150,16 @@ int Process::sys$accept(int accepting_socket_fd, Userspace user_addre return accepted_socket_fd; } -int Process::sys$connect(int sockfd, Userspace user_address, socklen_t user_address_size) +KResultOr Process::sys$connect(int sockfd, Userspace user_address, socklen_t user_address_size) { int fd = alloc_fd(); if (fd < 0) return fd; auto description = file_description(sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); @@ -167,79 +167,79 @@ int Process::sys$connect(int sockfd, Userspace user_address, so return socket.connect(*description, user_address, user_address_size, description->is_blocking() ? ShouldBlock::Yes : ShouldBlock::No); } -int Process::sys$shutdown(int sockfd, int how) +KResultOr Process::sys$shutdown(int sockfd, int how) { REQUIRE_PROMISE(stdio); if (how & ~SHUT_RDWR) - return -EINVAL; + return EINVAL; auto description = file_description(sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); return socket.shutdown(how); } -ssize_t Process::sys$sendmsg(int sockfd, Userspace user_msg, int flags) +KResultOr Process::sys$sendmsg(int sockfd, Userspace user_msg, int flags) { REQUIRE_PROMISE(stdio); struct msghdr msg; if (!copy_from_user(&msg, user_msg)) - return -EFAULT; + return EFAULT; if (msg.msg_iovlen != 1) - return -ENOTSUP; // FIXME: Support this :) + return ENOTSUP; // FIXME: Support this :) Vector iovs; iovs.resize(msg.msg_iovlen); if (!copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen)) - return -EFAULT; + return EFAULT; Userspace user_addr((FlatPtr)msg.msg_name); socklen_t addr_length = msg.msg_namelen; auto description = file_description(sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); if (socket.is_shut_down_for_writing()) - return -EPIPE; + return EPIPE; auto data_buffer = UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len); if (!data_buffer.has_value()) - return -EFAULT; + return EFAULT; auto result = socket.sendto(*description, data_buffer.value(), iovs[0].iov_len, flags, user_addr, addr_length); if (result.is_error()) return result.error(); return result.value(); } -ssize_t Process::sys$recvmsg(int sockfd, Userspace user_msg, int flags) +KResultOr Process::sys$recvmsg(int sockfd, Userspace user_msg, int flags) { REQUIRE_PROMISE(stdio); struct msghdr msg; if (!copy_from_user(&msg, user_msg)) - return -EFAULT; + return EFAULT; if (msg.msg_iovlen != 1) - return -ENOTSUP; // FIXME: Support this :) + return ENOTSUP; // FIXME: Support this :) Vector iovs; iovs.resize(msg.msg_iovlen); if (!copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen)) - return -EFAULT; + return EFAULT; Userspace user_addr((FlatPtr)msg.msg_name); Userspace user_addr_length(msg.msg_name ? (FlatPtr)&user_msg.unsafe_userspace_ptr()->msg_namelen : 0); auto description = file_description(sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); if (socket.is_shut_down_for_reading()) @@ -251,7 +251,7 @@ ssize_t Process::sys$recvmsg(int sockfd, Userspace user_msg, int auto data_buffer = UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len); if (!data_buffer.has_value()) - return -EFAULT; + return EFAULT; timeval timestamp = { 0, 0 }; auto result = socket.recvfrom(*description, data_buffer.value(), iovs[0].iov_len, flags, user_addr, user_addr_length, timestamp); if (flags & MSG_DONTWAIT) @@ -278,14 +278,14 @@ ssize_t Process::sys$recvmsg(int sockfd, Userspace user_msg, int } else { cmsg_timestamp = { { control_length, SOL_SOCKET, SCM_TIMESTAMP }, timestamp }; if (!copy_to_user(msg.msg_control, &cmsg_timestamp, control_length)) - return -EFAULT; + return EFAULT; } if (!copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_controllen, &control_length)) - return -EFAULT; + return EFAULT; } if (!copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_flags, &msg_flags)) - return -EFAULT; + return EFAULT; return result.value(); } @@ -295,17 +295,17 @@ int Process::get_sock_or_peer_name(const Params& params) { socklen_t addrlen_value; if (!copy_from_user(&addrlen_value, params.addrlen, sizeof(socklen_t))) - return -EFAULT; + return EFAULT; if (addrlen_value <= 0) - return -EINVAL; + return EINVAL; auto description = file_description(params.sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); @@ -317,33 +317,33 @@ int Process::get_sock_or_peer_name(const Params& params) else socket.get_peer_address((sockaddr*)address_buffer, &addrlen_value); if (!copy_to_user(params.addr, address_buffer, addrlen_value)) - return -EFAULT; + return EFAULT; if (!copy_to_user(params.addrlen, &addrlen_value)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$getsockname(Userspace user_params) +KResultOr Process::sys$getsockname(Userspace user_params) { Syscall::SC_getsockname_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; return get_sock_or_peer_name(params); } -int Process::sys$getpeername(Userspace user_params) +KResultOr Process::sys$getpeername(Userspace user_params) { Syscall::SC_getpeername_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; return get_sock_or_peer_name(params); } -int Process::sys$getsockopt(Userspace user_params) +KResultOr Process::sys$getsockopt(Userspace user_params) { Syscall::SC_getsockopt_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; int sockfd = params.sockfd; int level = params.level; @@ -353,30 +353,30 @@ int Process::sys$getsockopt(Userspace user socklen_t value_size; if (!copy_from_user(&value_size, params.value_size, sizeof(socklen_t))) - return -EFAULT; + return EFAULT; auto description = file_description(sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); return socket.getsockopt(*description, level, option, user_value, user_value_size); } -int Process::sys$setsockopt(Userspace user_params) +KResultOr Process::sys$setsockopt(Userspace user_params) { Syscall::SC_setsockopt_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; Userspace user_value((FlatPtr)params.value); auto description = file_description(params.sockfd); if (!description) - return -EBADF; + return EBADF; if (!description->is_socket()) - return -ENOTSOCK; + return ENOTSOCK; auto& socket = *description->socket(); REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); return socket.setsockopt(params.level, params.option, user_value, params.value_size); diff --git a/Kernel/Syscalls/stat.cpp b/Kernel/Syscalls/stat.cpp index 19cdb14f78..236eb39d8a 100644 --- a/Kernel/Syscalls/stat.cpp +++ b/Kernel/Syscalls/stat.cpp @@ -31,25 +31,25 @@ namespace Kernel { -int Process::sys$fstat(int fd, Userspace user_statbuf) +KResultOr Process::sys$fstat(int fd, Userspace user_statbuf) { REQUIRE_PROMISE(stdio); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; stat buffer = {}; int rc = description->stat(buffer); if (!copy_to_user(user_statbuf, &buffer)) - return -EFAULT; + return EFAULT; return rc; } -int Process::sys$stat(Userspace user_params) +KResultOr Process::sys$stat(Userspace user_params) { REQUIRE_PROMISE(rpath); Syscall::SC_stat_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; auto path = get_syscall_path_argument(params.path); if (path.is_error()) return path.error(); @@ -61,7 +61,7 @@ int Process::sys$stat(Userspace user_params) if (result.is_error()) return result; if (!copy_to_user(params.statbuf, &statbuf)) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/sync.cpp b/Kernel/Syscalls/sync.cpp index 928018e6b6..4b3dbcd881 100644 --- a/Kernel/Syscalls/sync.cpp +++ b/Kernel/Syscalls/sync.cpp @@ -29,7 +29,7 @@ namespace Kernel { -int Process::sys$sync() +KResultOr Process::sys$sync() { REQUIRE_PROMISE(stdio); VFS::the().sync(); diff --git a/Kernel/Syscalls/sysconf.cpp b/Kernel/Syscalls/sysconf.cpp index 7fee6fd741..4a3b13b7a5 100644 --- a/Kernel/Syscalls/sysconf.cpp +++ b/Kernel/Syscalls/sysconf.cpp @@ -30,7 +30,7 @@ namespace Kernel { -long Process::sys$sysconf(int name) +KResultOr Process::sys$sysconf(int name) { switch (name) { case _SC_NPROCESSORS_CONF: @@ -45,7 +45,7 @@ long Process::sys$sysconf(int name) case _SC_GETPW_R_SIZE_MAX: return 4096; // idk default: - return -EINVAL; + return EINVAL; } } diff --git a/Kernel/Syscalls/thread.cpp b/Kernel/Syscalls/thread.cpp index aa8be5aac5..edefb7702e 100644 --- a/Kernel/Syscalls/thread.cpp +++ b/Kernel/Syscalls/thread.cpp @@ -34,31 +34,31 @@ namespace Kernel { -int Process::sys$create_thread(void* (*entry)(void*), Userspace user_params) +KResultOr Process::sys$create_thread(void* (*entry)(void*), Userspace user_params) { REQUIRE_PROMISE(thread); Syscall::SC_create_thread_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; unsigned detach_state = params.m_detach_state; int schedule_priority = params.m_schedule_priority; unsigned stack_size = params.m_stack_size; if (Checked::addition_would_overflow((FlatPtr)params.m_stack_location, stack_size)) - return -EOVERFLOW; + return EOVERFLOW; auto user_stack_address = (u8*)params.m_stack_location + stack_size; if (!MM.validate_user_stack(*this, VirtualAddress(user_stack_address - 4))) - return -EFAULT; + return EFAULT; // FIXME: return EAGAIN if Thread::all_threads().size() is greater than PTHREAD_THREADS_MAX int requested_thread_priority = schedule_priority; if (requested_thread_priority < THREAD_PRIORITY_MIN || requested_thread_priority > THREAD_PRIORITY_MAX) - return -EINVAL; + return EINVAL; bool is_thread_joinable = (0 == detach_state); @@ -108,31 +108,31 @@ void Process::sys$exit_thread(Userspace exit_value) VERIFY_NOT_REACHED(); } -int Process::sys$detach_thread(pid_t tid) +KResultOr Process::sys$detach_thread(pid_t tid) { REQUIRE_PROMISE(thread); auto thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) - return -ESRCH; + return ESRCH; if (!thread->is_joinable()) - return -EINVAL; + return EINVAL; thread->detach(); return 0; } -int Process::sys$join_thread(pid_t tid, Userspace exit_value) +KResultOr Process::sys$join_thread(pid_t tid, Userspace exit_value) { REQUIRE_PROMISE(thread); auto thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) - return -ESRCH; + return ESRCH; auto current_thread = Thread::current(); if (thread == current_thread) - return -EDEADLK; + return EDEADLK; void* joinee_exit_value = nullptr; @@ -151,50 +151,50 @@ int Process::sys$join_thread(pid_t tid, Userspace exit_value) } if (exit_value && !copy_to_user(exit_value, &joinee_exit_value)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$set_thread_name(pid_t tid, Userspace user_name, size_t user_name_length) +KResultOr Process::sys$set_thread_name(pid_t tid, Userspace user_name, size_t user_name_length) { REQUIRE_PROMISE(stdio); auto name = copy_string_from_user(user_name, user_name_length); if (name.is_null()) - return -EFAULT; + return EFAULT; const size_t max_thread_name_size = 64; if (name.length() > max_thread_name_size) - return -EINVAL; + return EINVAL; auto thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) - return -ESRCH; + return ESRCH; thread->set_name(move(name)); return 0; } -int Process::sys$get_thread_name(pid_t tid, Userspace buffer, size_t buffer_size) +KResultOr Process::sys$get_thread_name(pid_t tid, Userspace buffer, size_t buffer_size) { REQUIRE_PROMISE(thread); if (buffer_size == 0) - return -EINVAL; + return EINVAL; auto thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) - return -ESRCH; + return ESRCH; // We must make a temporary copy here to avoid a race with sys$set_thread_name auto thread_name = thread->name(); if (thread_name.length() + 1 > (size_t)buffer_size) - return -ENAMETOOLONG; + return ENAMETOOLONG; if (!copy_to_user(buffer, thread_name.characters(), thread_name.length() + 1)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$gettid() +KResultOr Process::sys$gettid() { REQUIRE_PROMISE(stdio); return Thread::current()->tid().value(); diff --git a/Kernel/Syscalls/times.cpp b/Kernel/Syscalls/times.cpp index 30d5a76118..9656c67e47 100644 --- a/Kernel/Syscalls/times.cpp +++ b/Kernel/Syscalls/times.cpp @@ -28,7 +28,7 @@ namespace Kernel { -clock_t Process::sys$times(Userspace user_times) +KResultOr Process::sys$times(Userspace user_times) { REQUIRE_PROMISE(stdio); tms times = {}; @@ -38,7 +38,7 @@ clock_t Process::sys$times(Userspace user_times) times.tms_cstime = m_ticks_in_kernel_for_dead_children; if (!copy_to_user(user_times, ×)) - return -EFAULT; + return EFAULT; return TimeManagement::the().uptime_ms() & 0x7fffffff; } diff --git a/Kernel/Syscalls/ttyname.cpp b/Kernel/Syscalls/ttyname.cpp index 9f37a94768..381c284fd1 100644 --- a/Kernel/Syscalls/ttyname.cpp +++ b/Kernel/Syscalls/ttyname.cpp @@ -31,36 +31,36 @@ namespace Kernel { -int Process::sys$ttyname(int fd, Userspace buffer, size_t size) +KResultOr Process::sys$ttyname(int fd, Userspace buffer, size_t size) { REQUIRE_PROMISE(tty); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; if (!description->is_tty()) - return -ENOTTY; + return ENOTTY; auto tty_name = description->tty()->tty_name(); if (size < tty_name.length() + 1) - return -ERANGE; + return ERANGE; if (!copy_to_user(buffer, tty_name.characters(), tty_name.length() + 1)) - return -EFAULT; + return EFAULT; return 0; } -int Process::sys$ptsname(int fd, Userspace buffer, size_t size) +KResultOr Process::sys$ptsname(int fd, Userspace buffer, size_t size) { REQUIRE_PROMISE(tty); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; auto* master_pty = description->master_pty(); if (!master_pty) - return -ENOTTY; + return ENOTTY; auto pts_name = master_pty->pts_name(); if (size < pts_name.length() + 1) - return -ERANGE; + return ERANGE; if (!copy_to_user(buffer, pts_name.characters(), pts_name.length() + 1)) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/umask.cpp b/Kernel/Syscalls/umask.cpp index d465624b36..c2f0592136 100644 --- a/Kernel/Syscalls/umask.cpp +++ b/Kernel/Syscalls/umask.cpp @@ -28,7 +28,7 @@ namespace Kernel { -mode_t Process::sys$umask(mode_t mask) +KResultOr Process::sys$umask(mode_t mask) { REQUIRE_PROMISE(stdio); auto old_mask = m_umask; diff --git a/Kernel/Syscalls/uname.cpp b/Kernel/Syscalls/uname.cpp index 863d962e8b..d54e12d09f 100644 --- a/Kernel/Syscalls/uname.cpp +++ b/Kernel/Syscalls/uname.cpp @@ -28,7 +28,7 @@ namespace Kernel { -int Process::sys$uname(Userspace user_buf) +KResultOr Process::sys$uname(Userspace user_buf) { extern String* g_hostname; extern Lock* g_hostname_lock; @@ -37,7 +37,7 @@ int Process::sys$uname(Userspace user_buf) LOCKER(*g_hostname_lock, Lock::Mode::Shared); if (g_hostname->length() + 1 > sizeof(utsname::nodename)) - return -ENAMETOOLONG; + return ENAMETOOLONG; utsname buf {}; memcpy(buf.sysname, "SerenityOS", 11); @@ -47,7 +47,7 @@ int Process::sys$uname(Userspace user_buf) memcpy(buf.nodename, g_hostname->characters(), g_hostname->length() + 1); if (!copy_to_user(user_buf, &buf)) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/unlink.cpp b/Kernel/Syscalls/unlink.cpp index f7cf1faf22..b39ee42faf 100644 --- a/Kernel/Syscalls/unlink.cpp +++ b/Kernel/Syscalls/unlink.cpp @@ -30,7 +30,7 @@ namespace Kernel { -int Process::sys$unlink(Userspace user_path, size_t path_length) +KResultOr Process::sys$unlink(Userspace user_path, size_t path_length) { REQUIRE_PROMISE(cpath); auto path = get_syscall_path_argument(user_path, path_length); diff --git a/Kernel/Syscalls/unveil.cpp b/Kernel/Syscalls/unveil.cpp index 20a91edb69..cec3b63394 100644 --- a/Kernel/Syscalls/unveil.cpp +++ b/Kernel/Syscalls/unveil.cpp @@ -32,11 +32,11 @@ namespace Kernel { -int Process::sys$unveil(Userspace user_params) +KResultOr Process::sys$unveil(Userspace user_params) { Syscall::SC_unveil_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; if (!params.path.characters && !params.permissions.characters) { m_veil_state = VeilState::Locked; @@ -44,24 +44,24 @@ int Process::sys$unveil(Userspace user_params) } if (m_veil_state == VeilState::Locked) - return -EPERM; + return EPERM; if (!params.path.characters || !params.permissions.characters) - return -EINVAL; + return EINVAL; if (params.permissions.length > 5) - return -EINVAL; + return EINVAL; auto path = get_syscall_path_argument(params.path); if (path.is_error()) return path.error(); if (path.value().is_empty() || path.value().characters()[0] != '/') - return -EINVAL; + return EINVAL; auto permissions = copy_string_from_user(params.permissions); if (permissions.is_null()) - return -EFAULT; + return EFAULT; // Let's work out permissions first... unsigned new_permissions = 0; @@ -83,7 +83,7 @@ int Process::sys$unveil(Userspace user_params) new_permissions |= UnveilAccess::Browse; break; default: - return -EINVAL; + return EINVAL; } } @@ -114,7 +114,7 @@ int Process::sys$unveil(Userspace user_params) // as that would be the first time this path is unveiled. if (old_permissions != UnveilAccess::None || !matching_node.permissions_inherited_from_root()) { if (new_permissions & ~old_permissions) - return -EPERM; + return EPERM; } matching_node.set_metadata({ matching_node.path(), (UnveilAccess)new_permissions, true, false }); return 0; diff --git a/Kernel/Syscalls/utime.cpp b/Kernel/Syscalls/utime.cpp index ae848b906c..31b0509f36 100644 --- a/Kernel/Syscalls/utime.cpp +++ b/Kernel/Syscalls/utime.cpp @@ -30,7 +30,7 @@ namespace Kernel { -int Process::sys$utime(Userspace user_path, size_t path_length, Userspace user_buf) +KResultOr Process::sys$utime(Userspace user_path, size_t path_length, Userspace user_buf) { REQUIRE_PROMISE(fattr); auto path = get_syscall_path_argument(user_path, path_length); @@ -39,7 +39,7 @@ int Process::sys$utime(Userspace user_path, size_t path_length, Use utimbuf buf; if (user_buf) { if (!copy_from_user(&buf, user_buf)) - return -EFAULT; + return EFAULT; } else { auto now = kgettimeofday(); buf = { now.tv_sec, now.tv_sec }; diff --git a/Kernel/Syscalls/waitid.cpp b/Kernel/Syscalls/waitid.cpp index c2ca611a89..419f7a5338 100644 --- a/Kernel/Syscalls/waitid.cpp +++ b/Kernel/Syscalls/waitid.cpp @@ -38,13 +38,13 @@ KResultOr Process::do_waitid(idtype_t idtype, int id, int options) return result; } -pid_t Process::sys$waitid(Userspace user_params) +KResultOr Process::sys$waitid(Userspace user_params) { REQUIRE_PROMISE(proc); Syscall::SC_waitid_params params; if (!copy_from_user(¶ms, user_params)) - return -EFAULT; + return EFAULT; switch (params.idtype) { case P_ALL: @@ -62,7 +62,7 @@ pid_t Process::sys$waitid(Userspace user_param return siginfo_or_error.error(); if (!copy_to_user(params.infop, &siginfo_or_error.value())) - return -EFAULT; + return EFAULT; return 0; } diff --git a/Kernel/Syscalls/watch_file.cpp b/Kernel/Syscalls/watch_file.cpp index 2f6194bc7a..880cb67065 100644 --- a/Kernel/Syscalls/watch_file.cpp +++ b/Kernel/Syscalls/watch_file.cpp @@ -31,7 +31,7 @@ namespace Kernel { -int Process::sys$watch_file(Userspace user_path, size_t path_length) +KResultOr Process::sys$watch_file(Userspace user_path, size_t path_length) { REQUIRE_PROMISE(rpath); auto path = get_syscall_path_argument(user_path, path_length); @@ -46,7 +46,7 @@ int Process::sys$watch_file(Userspace user_path, size_t path_length auto& inode = custody->inode(); if (!inode.fs().supports_watchers()) - return -ENOTSUP; + return ENOTSUP; int fd = alloc_fd(); if (fd < 0) diff --git a/Kernel/Syscalls/write.cpp b/Kernel/Syscalls/write.cpp index e1006163ab..82d952e1e0 100644 --- a/Kernel/Syscalls/write.cpp +++ b/Kernel/Syscalls/write.cpp @@ -31,57 +31,57 @@ namespace Kernel { -ssize_t Process::sys$writev(int fd, Userspace iov, int iov_count) +KResultOr Process::sys$writev(int fd, Userspace iov, int iov_count) { REQUIRE_PROMISE(stdio); if (iov_count < 0) - return -EINVAL; + return EINVAL; // Arbitrary pain threshold. if (iov_count > (int)MiB) - return -EFAULT; + return EFAULT; u64 total_length = 0; Vector vecs; vecs.resize(iov_count); if (!copy_n_from_user(vecs.data(), iov, iov_count)) - return -EFAULT; + return EFAULT; for (auto& vec : vecs) { total_length += vec.iov_len; if (total_length > NumericLimits::max()) - return -EINVAL; + return EINVAL; } auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; if (!description->is_writable()) - return -EBADF; + return EBADF; int nwritten = 0; for (auto& vec : vecs) { auto buffer = UserOrKernelBuffer::for_user_buffer((u8*)vec.iov_base, vec.iov_len); if (!buffer.has_value()) - return -EFAULT; - int rc = do_write(*description, buffer.value(), vec.iov_len); - if (rc < 0) { + return EFAULT; + auto result = do_write(*description, buffer.value(), vec.iov_len); + if (result.is_error()) { if (nwritten == 0) - return rc; + return result.error(); return nwritten; } - nwritten += rc; + nwritten += result.value(); } return nwritten; } -ssize_t Process::do_write(FileDescription& description, const UserOrKernelBuffer& data, size_t data_size) +KResultOr Process::do_write(FileDescription& description, const UserOrKernelBuffer& data, size_t data_size) { ssize_t total_nwritten = 0; if (!description.is_blocking()) { if (!description.can_write()) - return -EAGAIN; + return EAGAIN; } if (description.should_append()) @@ -97,7 +97,7 @@ ssize_t Process::do_write(FileDescription& description, const UserOrKernelBuffer auto unblock_flags = Thread::FileBlocker::BlockFlags::None; if (Thread::current()->block({}, description, unblock_flags).was_interrupted()) { if (total_nwritten == 0) - return -EINTR; + return EINTR; } // TODO: handle exceptions in unblock_flags } @@ -114,24 +114,24 @@ ssize_t Process::do_write(FileDescription& description, const UserOrKernelBuffer return total_nwritten; } -ssize_t Process::sys$write(int fd, const u8* data, ssize_t size) +KResultOr Process::sys$write(int fd, const u8* data, ssize_t size) { REQUIRE_PROMISE(stdio); if (size < 0) - return -EINVAL; + return EINVAL; if (size == 0) return 0; dbgln_if(IO_DEBUG, "sys$write({}, {}, {})", fd, data, size); auto description = file_description(fd); if (!description) - return -EBADF; + return EBADF; if (!description->is_writable()) - return -EBADF; + return EBADF; auto buffer = UserOrKernelBuffer::for_user_buffer(const_cast(data), (size_t)size); if (!buffer.has_value()) - return -EFAULT; + return EFAULT; return do_write(*description, buffer.value(), size); }