emerald_std/
process.rs

1use core::ffi::{c_char, CStr};
2
3pub use kernel_user_link::process::{
4    process_metadata, PriorityLevel, ProcessMetadata, SpawnFileMapping,
5};
6use kernel_user_link::{
7    call_syscall,
8    syscalls::{SyscallError, SYS_EXIT, SYS_PRIORITY, SYS_SPAWN, SYS_WAIT_PID},
9};
10
11/// # Safety
12/// No guarantees are made about the state of the system after this function returns.
13pub unsafe fn exit(code: i32) -> ! {
14    unsafe {
15        call_syscall!(
16            SYS_EXIT,
17            code as u64, // code
18        )
19        .unwrap();
20    }
21    unreachable!("exit syscall should not return")
22}
23
24/// # Safety
25/// path must be a valid C string.
26/// argv must be a valid C string array. ending with a null pointer.
27/// File mappings must be valid and present file mappings.
28/// The fds used in the file mappings must never be used again by the caller, as the ownership is
29/// transferred to the child process.
30pub unsafe fn spawn(
31    path: &CStr,
32    argv: &[*const c_char],
33    file_mappings: &[SpawnFileMapping],
34) -> Result<u64, SyscallError> {
35    unsafe {
36        call_syscall!(
37            SYS_SPAWN,
38            path.as_ptr() as u64,          // path
39            argv.as_ptr() as u64,          // argv
40            file_mappings.as_ptr() as u64, // file_mappings
41            file_mappings.len() as u64     // file_mappings_len
42        )
43    }
44}
45
46/// # Safety
47/// This is generally safe, it will return error if the pid is not valid, but it might wait for a long
48/// time depending on the process we are waiting for.
49pub unsafe fn wait_for_pid(pid: u64, block: bool) -> Result<i32, SyscallError> {
50    unsafe {
51        call_syscall!(
52            SYS_WAIT_PID,
53            pid,          // pid
54            block as u64  // block
55        )
56        .map(|x| x as i32)
57    }
58}
59
60/// # Safety
61/// This is generally safe, it will return error if the pid is not valid, but its marked as unsafe
62/// because it's a syscall
63pub unsafe fn priority(
64    pid: u64,
65    priority_level: Option<PriorityLevel>,
66) -> Result<PriorityLevel, SyscallError> {
67    unsafe {
68        call_syscall!(
69            SYS_PRIORITY,
70            pid,                                      // pid
71            priority_level.map_or(0, |x| x.to_u64())  // priority_level
72        )
73        // this should never fail
74        .map(|x| PriorityLevel::from_u64(x).unwrap())
75    }
76}