safa_api/syscalls/
io.rs

1use safa_abi::{
2    errors::ErrorStatus,
3    ffi::slice::Slice,
4    fs::{DirEntry, FileAttr},
5};
6
7use crate::syscalls::types::{OptionalPtrMut, RequiredPtrMut, Ri};
8
9use super::{define_syscall, err_from_u16, SyscallNum};
10
11#[cfg(not(feature = "rustc-dep-of-std"))]
12extern crate alloc;
13
14// Directory Iterator related syscalls
15define_syscall! {
16    SyscallNum::SysFDirIterOpen =>
17    {
18        /// Opens a directory iterator for the directory with the resource id `dir_ri`
19        sysdiriter_open(dir_ri: Ri, dest_ri: RequiredPtrMut<Ri>)
20    },
21    SyscallNum::SysDirIterNext => {
22        /// Gets the next directory entry from a directory iterator,
23        ///
24        /// puts the results in `dest_direntry`,
25        ///
26        /// puts zeroed DirEntry in `dest_direntry` if there are no more entries
27        ///
28        /// returns [`ErrorStatus::Generic`] (1) if there are no more entries
29        sysdiriter_next(dir_ri: Ri, dest_direntry: OptionalPtrMut<DirEntry>)
30    }
31}
32
33#[inline]
34/// Opens a directory iterator for the directory with the resource id `dir_ri`,
35/// returns the resource id of the directory iterator
36///
37/// see [`sysdiriter_open`] for underlying syscall
38pub fn diriter_open(dir_ri: Ri) -> Result<Ri, ErrorStatus> {
39    let mut dest_fd: usize = 0xAAAAAAAAAAAAAAAAusize;
40    let ptr = unsafe { RequiredPtrMut::new_unchecked(&raw mut dest_fd) };
41    err_from_u16!(sysdiriter_open(dir_ri, ptr), dest_fd)
42}
43
44#[inline]
45/// Gets the next directory entry from a directory iterator,
46///
47/// see [`sysdiriter_next`] for underlying syscall
48pub fn diriter_next(dir_ri: Ri) -> Result<DirEntry, ErrorStatus> {
49    let mut dest_direntry: DirEntry = unsafe { core::mem::zeroed() };
50    let ptr = RequiredPtrMut::new(&raw mut dest_direntry).into();
51    err_from_u16!(sysdiriter_next(dir_ri, ptr), dest_direntry)
52}
53
54// File related syscalls
55define_syscall! {
56    SyscallNum::SysIOWrite => {
57        /// Writes `len` bytes from `buf` to the file with the resource id `fd` at offset `offset`
58        ///
59        /// if `dest_wrote` is not null, it will be set to the number of bytes written
60        syswrite(fd: Ri, offset: isize, buf: Slice<u8>, dest_wrote: OptionalPtrMut<usize>)
61    },
62    SyscallNum::SysIOTruncate => {
63        /// Truncates the file with the resource id `fd` to `len` bytes
64        systruncate(fd: Ri, len: usize)
65    },
66    SyscallNum::SysFSize => {
67        /// Gets the size of the file with the resource id `fd` and puts it in `dest_size`
68        sysfsize(fd: Ri, dest_size: OptionalPtrMut<usize>)
69    },
70    SyscallNum::SysFAttrs => {
71        /// Gets the file attributes of the file with the resource id `fd` and puts them in `dest_attrs`
72        sysfattrs(fd: Ri, dest_attrs: OptionalPtrMut<FileAttr>)
73    },
74    SyscallNum::SysIORead => {
75        /// Reads `len` bytes from the file with the resource id `fd` at offset `offset` into `buf`
76        ///
77        /// if `dest_read` is not null, it will be set to the number of bytes read
78        sysread(fd: Ri, offset: isize, buf: Slice<u8>, dest_read: OptionalPtrMut<usize>)
79    },
80    SyscallNum::SysIOSync => {
81        /// Syncs the resource with the resource id `fd`
82        syssync(ri: Ri)
83    },
84}
85
86#[inline]
87/// Writes `buf.len()` bytes from `buf` to the file with the resource id `fd` at offset `offset`
88/// and returns the number of bytes written
89pub fn write(fd: Ri, offset: isize, buf: &[u8]) -> Result<usize, ErrorStatus> {
90    let mut dest_wrote = 0;
91    let dest_wrote_ptr = RequiredPtrMut::new(&raw mut dest_wrote).into();
92    let slice = Slice::from_slice(buf);
93
94    err_from_u16!(syswrite(fd, offset, slice, dest_wrote_ptr), dest_wrote)
95}
96
97#[inline]
98/// Truncates the file with the resource id `fd` to `len` bytes
99pub fn truncate(fd: Ri, len: usize) -> Result<(), ErrorStatus> {
100    err_from_u16!(systruncate(fd, len))
101}
102
103#[inline]
104/// Gets the size of the file with the resource id `fd`
105pub fn fsize(fd: Ri) -> Result<usize, ErrorStatus> {
106    let mut dest_size = 0;
107    let ptr = RequiredPtrMut::new(&raw mut dest_size).into();
108    err_from_u16!(sysfsize(fd, ptr), dest_size)
109}
110
111#[inline]
112/// Gets the file attributes of the file with the resource id `fd`
113pub fn fattrs(fd: Ri) -> Result<FileAttr, ErrorStatus> {
114    let mut attrs: FileAttr = unsafe { core::mem::zeroed() };
115    let ptr = RequiredPtrMut::new(&raw mut attrs).into();
116    err_from_u16!(sysfattrs(fd, ptr), attrs)
117}
118
119#[inline]
120/// Reads `buf.len()` bytes from the file with the resource id `fd` at offset `offset` into `buf`
121pub fn read(fd: Ri, offset: isize, buf: &mut [u8]) -> Result<Ri, ErrorStatus> {
122    let mut dest_read = 0;
123    let dest_read_ptr = RequiredPtrMut::new(&raw mut dest_read).into();
124    let slice = Slice::from_slice(buf);
125    err_from_u16!(sysread(fd, offset, slice, dest_read_ptr), dest_read)
126}
127
128#[inline]
129/// Syncs the resource with the resource id `ri`
130pub fn sync(ri: Ri) -> Result<(), ErrorStatus> {
131    err_from_u16!(syssync(ri))
132}