1use super::{
2 arch::*,
3 data::{Map, Stat, StatVfs, StdFsCallMeta, TimeSpec},
4 error::Result,
5 flag::*,
6 number::*,
7};
8
9use core::mem;
10
11pub fn close(fd: usize) -> Result<usize> {
13 unsafe { syscall1(SYS_CLOSE, fd) }
14}
15
16pub fn clock_gettime(clock: usize, tp: &mut TimeSpec) -> Result<usize> {
18 unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) }
19}
20
21pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> {
23 unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) }
24}
25
26pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result<usize> {
28 unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) }
29}
30
31pub fn fchmod(fd: usize, mode: u16) -> Result<usize> {
33 unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) }
34}
35
36pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result<usize> {
38 unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) }
39}
40
41pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result<usize> {
43 unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) }
44}
45
46pub unsafe fn fmap(fd: usize, map: &Map) -> Result<usize> {
57 syscall3(
58 SYS_FMAP,
59 fd,
60 map as *const Map as usize,
61 mem::size_of::<Map>(),
62 )
63}
64
65pub unsafe fn funmap(addr: usize, len: usize) -> Result<usize> {
67 syscall2(SYS_FUNMAP, addr, len)
68}
69
70pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
72 unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) }
73}
74
75pub fn flink<T: AsRef<str>>(fd: usize, path: T) -> Result<usize> {
77 let path = path.as_ref();
78 unsafe { syscall3(SYS_FLINK, fd, path.as_ptr() as usize, path.len()) }
79}
80
81pub fn frename<T: AsRef<str>>(fd: usize, path: T) -> Result<usize> {
83 let path = path.as_ref();
84 unsafe { syscall3(SYS_FRENAME, fd, path.as_ptr() as usize, path.len()) }
85}
86
87pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
89 unsafe {
90 syscall3(
91 SYS_FSTAT,
92 fd,
93 stat as *mut Stat as usize,
94 mem::size_of::<Stat>(),
95 )
96 }
97}
98
99pub fn fstatvfs(fd: usize, stat: &mut StatVfs) -> Result<usize> {
101 unsafe {
102 syscall3(
103 SYS_FSTATVFS,
104 fd,
105 stat as *mut StatVfs as usize,
106 mem::size_of::<StatVfs>(),
107 )
108 }
109}
110
111pub fn fsync(fd: usize) -> Result<usize> {
113 unsafe { syscall1(SYS_FSYNC, fd) }
114}
115
116pub fn ftruncate(fd: usize, len: usize) -> Result<usize> {
118 unsafe { syscall2(SYS_FTRUNCATE, fd, len) }
119}
120
121pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result<usize> {
123 unsafe {
124 syscall3(
125 SYS_FUTIMENS,
126 fd,
127 times.as_ptr() as usize,
128 mem::size_of_val(times),
129 )
130 }
131}
132
133pub unsafe fn futex(
135 addr: *mut i32,
136 op: usize,
137 val: i32,
138 val2: usize,
139 addr2: *mut i32,
140) -> Result<usize> {
141 syscall5(
142 SYS_FUTEX,
143 addr as usize,
144 op,
145 (val as isize) as usize,
146 val2,
147 addr2 as usize,
148 )
149}
150
151pub fn lseek(fd: usize, offset: isize, whence: usize) -> Result<usize> {
153 unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) }
154}
155
156pub fn mkns(schemes: &[[usize; 2]]) -> Result<usize> {
158 unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) }
159}
160
161pub unsafe fn mprotect(addr: usize, size: usize, flags: MapFlags) -> Result<usize> {
163 syscall3(SYS_MPROTECT, addr, size, flags.bits())
164}
165
166pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result<usize> {
168 unsafe {
169 syscall2(
170 SYS_NANOSLEEP,
171 req as *const TimeSpec as usize,
172 rem as *mut TimeSpec as usize,
173 )
174 }
175}
176
177pub fn openat<T: AsRef<str>>(
179 fd: usize,
180 path: T,
181 flags: usize,
182 fcntl_flags: usize,
183) -> Result<usize> {
184 let path = path.as_ref();
185 unsafe {
186 syscall5(
187 SYS_OPENAT,
188 fd,
189 path.as_ptr() as usize,
190 path.len(),
191 flags,
192 fcntl_flags,
193 )
194 }
195}
196pub fn openat_with_filter<T: AsRef<str>>(
198 fd: usize,
199 path: T,
200 flags: usize,
201 fcntl_flags: usize,
202 euid: u32,
203 egid: u32,
204) -> Result<usize> {
205 let path = path.as_ref();
206 unsafe {
207 syscall6(
208 SYS_OPENAT_WITH_FILTER,
209 fd,
210 path.as_ptr() as usize,
211 path.len(),
212 flags | fcntl_flags,
213 euid as usize,
217 egid as usize,
218 )
219 }
220}
221
222pub fn unlinkat<T: AsRef<str>>(fd: usize, path: T, flags: usize) -> Result<usize> {
224 let path = path.as_ref();
225 unsafe { syscall4(SYS_UNLINKAT, fd, path.as_ptr() as usize, path.len(), flags) }
226}
227pub fn unlinkat_with_filter<T: AsRef<str>>(
229 fd: usize,
230 path: T,
231 flags: usize,
232 euid: u32,
233 egid: u32,
234) -> Result<usize> {
235 let path = path.as_ref();
236 unsafe {
237 syscall6(
238 SYS_UNLINKAT_WITH_FILTER,
239 fd,
240 path.as_ptr() as usize,
241 path.len(),
242 flags,
243 euid as usize,
247 egid as usize,
248 )
249 }
250}
251
252pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
254 unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) }
255}
256
257pub fn write(fd: usize, buf: &[u8]) -> Result<usize> {
272 unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) }
273}
274
275pub fn sched_yield() -> Result<usize> {
279 unsafe { syscall0(SYS_YIELD) }
280}
281
282pub fn sendfd(receiver_socket: usize, fd: usize, flags: usize, arg: u64) -> Result<usize> {
287 #[cfg(target_pointer_width = "32")]
288 unsafe {
289 syscall5(
290 SYS_SENDFD,
291 receiver_socket,
292 fd,
293 flags,
294 arg as u32 as usize,
295 (arg >> 32) as u32 as usize,
296 )
297 }
298
299 #[cfg(target_pointer_width = "64")]
300 unsafe {
301 syscall4(SYS_SENDFD, receiver_socket, fd, flags, arg as usize)
302 }
303}
304
305pub trait Call {
306 unsafe fn raw_call(
307 &self,
308 payload_ptr: *const u8,
309 len: usize,
310 flags: CallFlags,
311 metadata: &[u64],
312 ) -> Result<usize>;
313}
314
315impl Call for usize {
316 unsafe fn raw_call(
317 &self,
318 payload_ptr: *const u8,
319 len: usize,
320 flags: CallFlags,
321 metadata: &[u64],
322 ) -> Result<usize> {
323 unsafe {
324 syscall5(
325 SYS_CALL,
326 *self,
327 payload_ptr as usize,
328 len,
329 metadata.len() | flags.bits(),
330 metadata.as_ptr() as usize,
331 )
332 }
333 }
334}
335
336impl Call for &[usize] {
337 unsafe fn raw_call(
338 &self,
339 payload_ptr: *const u8,
340 len: usize,
341 flags: CallFlags,
342 metadata: &[u64],
343 ) -> Result<usize> {
344 let combined_flags = flags | CallFlags::MULTIPLE_FDS;
345 unsafe {
346 syscall6(
347 SYS_CALL,
348 self.as_ptr() as usize,
349 payload_ptr as usize,
350 len,
351 metadata.len() | combined_flags.bits(),
352 metadata.as_ptr() as usize,
353 self.len() * mem::size_of::<usize>(),
354 )
355 }
356 }
357}
358
359pub fn call_ro<T: Call>(
361 fd: T,
362 payload: &mut [u8],
363 flags: CallFlags,
364 metadata: &[u64],
365) -> Result<usize> {
366 unsafe {
367 fd.raw_call(
368 payload.as_mut_ptr(),
369 payload.len(),
370 flags | CallFlags::READ,
371 metadata,
372 )
373 }
374}
375pub fn call_wo<T: Call>(
377 fd: T,
378 payload: &[u8],
379 flags: CallFlags,
380 metadata: &[u64],
381) -> Result<usize> {
382 unsafe {
383 fd.raw_call(
384 payload.as_ptr(),
385 payload.len(),
386 flags | CallFlags::WRITE,
387 metadata,
388 )
389 }
390}
391pub fn call_rw<T: Call>(
393 fd: T,
394 payload: &mut [u8],
395 flags: CallFlags,
396 metadata: &[u64],
397) -> Result<usize> {
398 unsafe {
399 fd.raw_call(
400 payload.as_mut_ptr(),
401 payload.len(),
402 flags | CallFlags::READ | CallFlags::WRITE,
403 metadata,
404 )
405 }
406}
407
408pub fn std_fs_call<T: Call>(fd: T, payload: &mut [u8], metadata: &StdFsCallMeta) -> Result<usize> {
409 call_rw(fd, payload, CallFlags::STD_FS, metadata)
410}