1use super::{
2 arch::*,
3 data::{Map, Stat, StdFsCallMeta, TimeSpec},
4 error::Result,
5 flag::*,
6 number::*,
7};
8
9use core::mem;
10
11pub fn clock_gettime(clock: usize, tp: &mut TimeSpec) -> Result<usize> {
13 unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) }
14}
15
16pub fn dup_into(fd: usize, out: usize, buf: &[u8]) -> Result<usize> {
18 unsafe { syscall4(SYS_DUP_INTO, fd, buf.as_ptr() as usize, buf.len(), out) }
19}
20
21pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result<usize> {
23 unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) }
24}
25
26pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result<usize> {
28 unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) }
29}
30
31pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result<usize> {
33 unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) }
34}
35
36pub unsafe fn fmap(fd: usize, map: &Map) -> Result<usize> {
47 syscall3(
48 SYS_FMAP,
49 fd,
50 map as *const Map as usize,
51 mem::size_of::<Map>(),
52 )
53}
54
55pub unsafe fn funmap(addr: usize, len: usize) -> Result<usize> {
57 syscall2(SYS_FUNMAP, addr, len)
58}
59
60pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
62 unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) }
63}
64
65pub fn flink<T: AsRef<str>>(fd: usize, path: T) -> Result<usize> {
67 let path = path.as_ref();
68 unsafe { syscall3(SYS_FLINK, fd, path.as_ptr() as usize, path.len()) }
69}
70
71pub fn frename<T: AsRef<str>>(fd: usize, path: T) -> Result<usize> {
73 let path = path.as_ref();
74 unsafe { syscall3(SYS_FRENAME, fd, path.as_ptr() as usize, path.len()) }
75}
76
77pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
79 unsafe {
80 syscall3(
81 SYS_FSTAT,
82 fd,
83 stat as *mut Stat as usize,
84 mem::size_of::<Stat>(),
85 )
86 }
87}
88
89pub fn fsync(fd: usize) -> Result<usize> {
91 unsafe { syscall1(SYS_FSYNC, fd) }
92}
93
94pub unsafe fn futex(
96 addr: *mut i32,
97 op: usize,
98 val: i32,
99 val2: usize,
100 addr2: *mut i32,
101) -> Result<usize> {
102 syscall5(
103 SYS_FUTEX,
104 addr as usize,
105 op,
106 (val as isize) as usize,
107 val2,
108 addr2 as usize,
109 )
110}
111
112pub fn lseek(fd: usize, offset: isize, whence: usize) -> Result<usize> {
114 unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) }
115}
116
117pub unsafe fn mprotect(addr: usize, size: usize, flags: MapFlags) -> Result<usize> {
119 syscall3(SYS_MPROTECT, addr, size, flags.bits())
120}
121
122pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result<usize> {
124 unsafe {
125 syscall2(
126 SYS_NANOSLEEP,
127 req as *const TimeSpec as usize,
128 rem as *mut TimeSpec as usize,
129 )
130 }
131}
132
133pub fn openat_into(
135 fd: usize,
136 out: usize,
137 path: impl AsRef<str>,
138 flags: usize,
139 fcntl_flags: usize,
140) -> Result<usize> {
141 let path = path.as_ref();
142 unsafe {
143 syscall5(
144 SYS_OPENAT_INTO2,
145 fd,
146 path.as_ptr() as usize,
147 path.len() | (fcntl_flags & O_FCNTL_MASK),
148 flags,
149 out,
150 )
151 }
152}
153
154pub fn unlinkat<T: AsRef<str>>(fd: usize, path: T, flags: usize) -> Result<usize> {
156 let path = path.as_ref();
157 unsafe { syscall4(SYS_UNLINKAT, fd, path.as_ptr() as usize, path.len(), flags) }
158}
159pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
161 unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) }
162}
163
164pub fn write(fd: usize, buf: &[u8]) -> Result<usize> {
179 unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) }
180}
181
182pub fn sched_yield() -> Result<usize> {
186 unsafe { syscall0(SYS_YIELD) }
187}
188
189pub trait Call {
190 #[inline]
191 fn extra_flags(&self) -> CallFlags {
192 CallFlags::empty()
193 }
194 unsafe fn raw_call(
195 &self,
196 payload_ptr: *const u8,
197 len: usize,
198 flags: CallFlags,
199 metadata: &[u64],
200 ) -> Result<usize>;
201}
202
203impl Call for usize {
204 unsafe fn raw_call(
205 &self,
206 payload_ptr: *const u8,
207 len: usize,
208 flags: CallFlags,
209 metadata: &[u64],
210 ) -> Result<usize> {
211 unsafe {
212 syscall5(
213 SYS_CALL,
214 *self,
215 payload_ptr as usize,
216 len,
217 metadata.len() | flags.bits(),
218 metadata.as_ptr() as usize,
219 )
220 }
221 }
222}
223
224impl Call for &[usize] {
225 #[inline]
226 fn extra_flags(&self) -> CallFlags {
227 CallFlags::MULTIPLE_FDS2
228 }
229 unsafe fn raw_call(
230 &self,
231 payload_ptr: *const u8,
232 len: usize,
233 flags: CallFlags,
234 metadata: &[u64],
235 ) -> Result<usize> {
236 if self.len() > core::mem::align_of::<usize>() {
239 return Err(crate::error::Error::new(crate::error::EINVAL));
240 }
241 unsafe {
242 syscall5(
243 SYS_CALL,
244 self.as_ptr() as usize | self.len(),
245 payload_ptr as usize,
246 len,
247 metadata.len() | flags.bits(),
248 metadata.as_ptr() as usize,
249 )
250 }
251 }
252}
253
254pub fn call_ro<T: Call>(
256 fd: T,
257 payload: &mut [u8],
258 flags: CallFlags,
259 metadata: &[u64],
260) -> Result<usize> {
261 let combined_flags = flags | fd.extra_flags();
262 unsafe {
263 fd.raw_call(
264 payload.as_mut_ptr(),
265 payload.len(),
266 combined_flags | CallFlags::READ,
267 metadata,
268 )
269 }
270}
271pub fn call_wo<T: Call>(
273 fd: T,
274 payload: &[u8],
275 flags: CallFlags,
276 metadata: &[u64],
277) -> Result<usize> {
278 let combined_flags = flags | fd.extra_flags();
279 unsafe {
280 fd.raw_call(
281 payload.as_ptr(),
282 payload.len(),
283 combined_flags | CallFlags::WRITE,
284 metadata,
285 )
286 }
287}
288pub fn call_rw<T: Call>(
290 fd: T,
291 payload: &mut [u8],
292 flags: CallFlags,
293 metadata: &[u64],
294) -> Result<usize> {
295 let combined_flags = flags | fd.extra_flags();
296 unsafe {
297 fd.raw_call(
298 payload.as_mut_ptr(),
299 payload.len(),
300 combined_flags | CallFlags::READ | CallFlags::WRITE,
301 metadata,
302 )
303 }
304}
305
306pub fn std_fs_call<T: Call>(fd: T, payload: &mut [u8], metadata: &StdFsCallMeta) -> Result<usize> {
307 call_rw(fd, payload, CallFlags::STD_FS, metadata)
308}