1#[cfg(not(feature = "rustc-dep-of-std"))]
5extern crate alloc;
6
7use super::types::{
8 OptionalPtrMut, OptionalStrPtr, Pid, RequiredPtr, RequiredPtrMut, Ri, StrPtr, StrPtrMut,
9 SyscallResult,
10};
11use super::SyscallNum;
12use super::{define_syscall, DirEntry, FileAttr, RawSlice, RawSliceMut};
13use super::{err_from_u16, ErrorStatus};
14use crate::process::stdio::{sysmeta_stderr, sysmeta_stdin, sysmeta_stdout};
15use alloc::vec::Vec;
16use core::ptr;
17use safa_abi::raw::processes::{SpawnFlags, TaskStdio};
18use safa_abi::raw::Optional;
19
20define_syscall!(SyscallNum::SysGetDirEntry => {
21 sysgetdirentry(path_ptr: StrPtr, path_len: usize, dest_direntry: OptionalPtrMut<DirEntry>)
25});
26
27#[inline]
28pub fn getdirentry(path: &str) -> Result<DirEntry, ErrorStatus> {
29 let mut dest_direntry: DirEntry = unsafe { core::mem::zeroed() };
30 err_from_u16!(
31 sysgetdirentry(path.as_ptr(), path.len(), &raw mut dest_direntry),
32 dest_direntry
33 )
34}
35
36define_syscall! {
37 SyscallNum::SysOpen => {
38 sysopen(path_ptr: StrPtr, path_len: usize, dest_fd: *mut Ri)
42 },
43 SyscallNum::SysCreate => {
44 syscreate_file(path_ptr: StrPtr, path_len: usize)
47 },
48 SyscallNum::SysCreateDir => {
49 syscreate_dir(path_ptr: StrPtr, path_len: usize)
53 },
54 SyscallNum::SysClose => {
55 sysclose(fd: Ri)
57 }
58}
59
60#[inline]
61pub fn open(path: &str) -> Result<Ri, ErrorStatus> {
65 let mut dest_fd = 0xAAAAAAAAAAAAAAAAusize;
66 err_from_u16!(
67 sysopen(path.as_ptr(), path.len(), &raw mut dest_fd),
68 dest_fd
69 )
70}
71
72#[inline]
73pub fn create(path: &str) -> Result<(), ErrorStatus> {
77 err_from_u16!(syscreate_file(path.as_ptr(), path.len()))
78}
79
80#[inline]
81pub fn createdir(path: &str) -> Result<(), ErrorStatus> {
85 err_from_u16!(syscreate_dir(path.as_ptr(), path.len()))
86}
87
88#[inline]
89pub fn close(fd: Ri) -> Result<(), ErrorStatus> {
93 err_from_u16!(sysclose(fd))
94}
95
96define_syscall! {
98 SyscallNum::SysDirIterOpen =>
99 {
100 sysdiriter_open(dir_ri: Ri, dest_ri: RequiredPtrMut<Ri>)
102 },
103 SyscallNum::SysDirIterClose => {
104 sysdiriter_close(fd: Ri)
106 },
107 SyscallNum::SysDirIterNext => {
108 sysdiriter_next(dir_ri: Ri, dest_direntry: OptionalPtrMut<DirEntry>)
116 }
117}
118
119#[inline]
120pub fn diriter_close(fd: Ri) -> Result<(), ErrorStatus> {
124 err_from_u16!(sysdiriter_close(fd))
125}
126
127#[inline]
128pub fn diriter_open(dir_ri: Ri) -> Result<Ri, ErrorStatus> {
133 let mut dest_fd: usize = 0xAAAAAAAAAAAAAAAAusize;
134 err_from_u16!(sysdiriter_open(dir_ri, &raw mut dest_fd), dest_fd)
135}
136
137#[inline]
138pub fn diriter_next(dir_ri: Ri) -> Result<DirEntry, ErrorStatus> {
142 let mut dest_direntry: DirEntry = unsafe { core::mem::zeroed() };
143 err_from_u16!(
144 sysdiriter_next(dir_ri, &raw mut dest_direntry),
145 dest_direntry
146 )
147}
148
149define_syscall! {
151 SyscallNum::SysWrite => {
152 syswrite(fd: Ri, offset: isize, buf: RequiredPtr<u8>, len: usize, dest_wrote: OptionalPtrMut<usize>)
156 },
157 SyscallNum::SysTruncate => {
158 systruncate(fd: Ri, len: usize)
160 },
161 SyscallNum::SysFSize => {
162 sysfsize(fd: Ri, dest_size: OptionalPtrMut<usize>)
164 },
165 SyscallNum::SysFAttrs => {
166 sysfattrs(fd: Ri, dest_attrs: OptionalPtrMut<FileAttr>)
168 },
169 SyscallNum::SysRead => {
170 sysread(fd: Ri, offset: isize, buf: RequiredPtrMut<u8>, len: usize, dest_read: OptionalPtrMut<usize>)
174 },
175 SyscallNum::SysSync => {
176 syssync(ri: Ri)
178 },
179 SyscallNum::SysDup => {
180 sysdup(ri: Ri, dest_ri: RequiredPtrMut<Ri>)
182 }
183}
184
185#[inline]
186pub fn write(fd: Ri, offset: isize, buf: &[u8]) -> Result<usize, ErrorStatus> {
189 let mut dest_wrote = 0;
190 err_from_u16!(
191 syswrite(fd, offset, buf.as_ptr(), buf.len(), &mut dest_wrote),
192 dest_wrote
193 )
194}
195
196#[inline]
197pub fn truncate(fd: Ri, len: usize) -> Result<(), ErrorStatus> {
199 err_from_u16!(systruncate(fd, len))
200}
201
202#[inline]
203pub fn fsize(fd: Ri) -> Result<usize, ErrorStatus> {
205 let mut dest_size = 0;
206 err_from_u16!(sysfsize(fd, &raw mut dest_size), dest_size)
207}
208
209#[inline]
210pub fn fattrs(fd: Ri) -> Result<FileAttr, ErrorStatus> {
212 let mut attrs: FileAttr = unsafe { core::mem::zeroed() };
213 err_from_u16!(sysfattrs(fd, &raw mut attrs), attrs)
214}
215
216#[inline]
217pub fn read(fd: Ri, offset: isize, buf: &mut [u8]) -> Result<Ri, ErrorStatus> {
219 let mut dest_read = 0;
220 err_from_u16!(
221 sysread(fd, offset, buf.as_mut_ptr(), buf.len(), &mut dest_read),
222 dest_read
223 )
224}
225
226#[inline]
227pub fn sync(ri: Ri) -> Result<(), ErrorStatus> {
229 err_from_u16!(syssync(ri))
230}
231
232#[inline]
233pub fn dup(ri: Ri) -> Result<Ri, ErrorStatus> {
236 let mut dest_ri = 0xAAAAAAAAAAAAAAAAusize;
237 err_from_u16!(sysdup(ri, &mut dest_ri), dest_ri)
238}
239
240define_syscall! {
242 SyscallNum::SysSbrk => {
243 syssbrk(size: isize, target_ptr: OptionalPtrMut<*mut u8>)
245 },
246 SyscallNum::SysExit => {
247 sysexit(code: usize) unreachable
249 },
250 SyscallNum::SysYield => {
251 sysyield()
253 },
254 SyscallNum::SysWait => {
255 syswait(pid: Pid, exit_code: *mut usize)
258 },
259 SyscallNum::SysCHDir => {
260 syschdir(buf_ptr: StrPtr, buf_len: usize)
263 },
264 SyscallNum::SysGetCWD => {
265 sysgetcwd(cwd_buf: StrPtrMut, cwd_buf_len: usize, dest_len: OptionalPtrMut<usize>)
270 }
271}
272
273#[inline]
274pub fn sbrk(size: isize) -> Result<*mut u8, ErrorStatus> {
279 let mut target_ptr: *mut u8 = core::ptr::null_mut();
280 err_from_u16!(syssbrk(size, &mut target_ptr), target_ptr)
281}
282
283#[inline]
284pub fn exit(code: usize) -> ! {
285 sysexit(code)
286}
287
288#[inline]
289pub fn yield_now() {
290 debug_assert!(sysyield().is_success())
291}
292
293#[inline]
294pub fn wait(pid: Pid) -> Result<usize, ErrorStatus> {
299 let mut dest_exit_code = 0;
300 err_from_u16!(syswait(pid, &mut dest_exit_code), dest_exit_code)
301}
302
303#[inline]
304pub fn chdir(path: &str) -> Result<(), ErrorStatus> {
306 let path = path.as_bytes();
307 err_from_u16!(syschdir(path.as_ptr(), path.len()))
308}
309
310use alloc::string::String;
311#[inline]
312pub fn getcwd() -> Result<String, ErrorStatus> {
314 let mut buffer = Vec::with_capacity(safa_abi::consts::MAX_PATH_LENGTH);
315 unsafe {
316 buffer.set_len(buffer.capacity());
317 }
318
319 let mut dest_len: usize = 0xAAAAAAAAAAAAAAAAusize;
320 let len = err_from_u16!(
321 sysgetcwd(buffer.as_mut_ptr(), buffer.len(), &raw mut dest_len),
322 dest_len
323 )?;
324
325 buffer.truncate(len);
326 unsafe { Ok(String::from_utf8_unchecked(buffer)) }
327}
328
329define_syscall! {
330 SyscallNum::SysShutdown => {
331 sysshutdown() unreachable
333 },
334 SyscallNum::SysReboot => {
335 sysreboot() unreachable
337 }
338}
339
340#[inline]
341pub fn shutdown() -> ! {
342 sysshutdown()
343}
344
345#[inline]
346pub fn reboot() -> ! {
347 sysreboot()
348}
349
350#[cfg_attr(
352 not(any(feature = "std", feature = "rustc-dep-of-std")),
353 unsafe(no_mangle)
354)]
355#[inline(always)]
356extern "C" fn syspspawn(
363 name_ptr: OptionalStrPtr,
364 name_len: usize,
365 path_ptr: StrPtr,
366 path_len: usize,
367 argv_ptr: OptionalPtrMut<RawSlice<u8>>,
368 argv_len: usize,
369 env_ptr: OptionalPtrMut<RawSlice<u8>>,
370 env_len: usize,
371 flags: SpawnFlags,
372 dest_pid: OptionalPtrMut<Pid>,
373 stdin: Optional<Ri>,
374 stdout: Optional<Ri>,
375 stderr: Optional<Ri>,
376) -> SyscallResult {
377 use safa_abi::raw::processes::SpawnConfig;
378 let (mut stdin, mut stdout, mut stderr): (Option<_>, Option<_>, Option<_>) =
379 (stdin.into(), stdout.into(), stderr.into());
380
381 let stdio = {
382 if stdin.is_none() && stdout.is_none() && stderr.is_none() {
383 None
384 } else {
385 stdout.get_or_insert_with(|| sysmeta_stdout());
386 stdin.get_or_insert_with(|| sysmeta_stdin());
387 stderr.get_or_insert_with(|| sysmeta_stderr());
388
389 Some(TaskStdio::new(stdout, stdin, stderr))
390 }
391 };
392
393 let stdio = stdio.as_ref();
394 let stdio_ptr = stdio.map(|m| m as *const _).unwrap_or(core::ptr::null());
395
396 let config = SpawnConfig {
397 version: 1,
398 name: unsafe { RawSlice::from_raw_parts(name_ptr, name_len) },
399 argv: unsafe { RawSliceMut::from_raw_parts(argv_ptr, argv_len) },
400 env: unsafe { RawSliceMut::from_raw_parts(env_ptr, env_len) },
401 flags,
402 stdio: stdio_ptr,
403 };
404 syscall!(
405 SyscallNum::SysPSpawn,
406 path_ptr as usize,
407 path_len,
408 (&raw const config) as usize,
409 dest_pid as *mut _ as usize,
410 )
411}
412
413#[inline]
420pub unsafe fn unsafe_pspawn(
421 name: Option<&str>,
422 path: &str,
423 argv: *mut [&str],
424 flags: SpawnFlags,
425 stdin: Option<Ri>,
426 stdout: Option<Ri>,
427 stderr: Option<Ri>,
428) -> Result<Pid, ErrorStatus> {
429 let mut pid = 0;
430
431 let name = name.map(|s| s.as_bytes());
432 let name_ptr = name.map(|s| s.as_ptr()).unwrap_or(ptr::null());
433 let name_len = name.map(|s| s.len()).unwrap_or(0);
434
435 let argv = argv as *mut [&[u8]];
436 let argv = unsafe { RawSliceMut::from_slices(argv) };
437 let (_, mut env) = crate::process::env::duplicate_env();
438
439 err_from_u16!(
440 syspspawn(
441 name_ptr,
442 name_len,
443 path.as_ptr(),
444 path.len(),
445 argv.as_mut_ptr(),
446 argv.len(),
447 env.as_mut_ptr(),
448 env.len(),
449 flags,
450 &mut pid,
451 stdin.into(),
452 stdout.into(),
453 stderr.into(),
454 ),
455 pid
456 )
457}
458
459#[inline]
467pub fn pspawn(
468 name: Option<&str>,
469 path: &str,
470 mut argv: Vec<&str>,
471 flags: SpawnFlags,
472 stdin: Option<Ri>,
473 stdout: Option<Ri>,
474 stderr: Option<Ri>,
475) -> Result<Pid, ErrorStatus> {
476 let argv: &mut [&str] = &mut argv;
477 unsafe { unsafe_pspawn(name, path, argv as *mut _, flags, stdin, stdout, stderr) }
478}