#include "memory/MemoryManager.h" #include "sys/Syscall.h" #include "thread/Scheduler.h" #include static void set_timespec(struct timespec& ts, u64 ticks) { ts.tv_sec = ticks / 1000; ts.tv_nsec = (ticks % 1000) * 1000 * 1000; } Result sys_pstat(Registers*, SyscallArgs args) { pid_t pid = (pid_t)args[0]; struct process* ps = (struct process*)args[1]; // If pid == -1, return the PID of the last spawned thread. if (pid == -1) return g_threads.expect_last()->id; auto* thread = TRY(Result::from_option(Scheduler::find_by_pid(pid), ESRCH)); struct process proc; proc.ps_pid = thread->id; proc.ps_ppid = thread->parent ? thread->parent->id : 0; proc.ps_uid = thread->auth.uid; proc.ps_gid = thread->auth.gid; proc.ps_euid = thread->auth.euid; proc.ps_egid = thread->auth.egid; proc.ps_state = (int)thread->state; proc.ps_flags = thread->is_kernel ? PS_FLAG_KRNL : 0; set_timespec(proc.ps_time, thread->user_ticks_self + thread->kernel_ticks_self); set_timespec(proc.ps_ktime, thread->kernel_ticks_self); set_timespec(proc.ps_utime, thread->kernel_ticks_children); strlcpy(proc.ps_name, thread->name.chars(), sizeof(proc.ps_name)); strlcpy(proc.ps_cwd, thread->current_directory_path.is_empty() ? "/" : thread->current_directory_path.chars(), sizeof(proc.ps_cwd)); if (!MemoryManager::copy_to_user_typed(ps, &proc)) return err(EFAULT); return (u64)pid; }