42 lines
1.5 KiB
C++
42 lines
1.5 KiB
C++
#include "memory/MemoryManager.h"
|
|
#include "sys/Syscall.h"
|
|
#include "thread/Scheduler.h"
|
|
#include <bits/pstat.h>
|
|
|
|
static void set_timespec(struct timespec& ts, u64 ticks)
|
|
{
|
|
ts.tv_sec = ticks / 1000;
|
|
ts.tv_nsec = (ticks % 1000) * 1000 * 1000;
|
|
}
|
|
|
|
Result<u64> 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<Thread*>::from_option(Scheduler::find_by_pid(pid), ESRCH));
|
|
|
|
struct process proc;
|
|
proc.ps_pid = (pid_t)thread->id;
|
|
proc.ps_ppid = thread->parent ? (pid_t)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;
|
|
}
|