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 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 fchmod(fd: usize, mode: u16) -> Result<usize> {
28 unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) }
29}
30
31pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result<usize> {
33 unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) }
34}
35
36pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result<usize> {
38 unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) }
39}
40
41pub unsafe fn fmap(fd: usize, map: &Map) -> Result<usize> {
52 syscall3(
53 SYS_FMAP,
54 fd,
55 map as *const Map as usize,
56 mem::size_of::<Map>(),
57 )
58}
59
60pub unsafe fn funmap(addr: usize, len: usize) -> Result<usize> {
62 syscall2(SYS_FUNMAP, addr, len)
63}
64
65pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
67 unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) }
68}
69
70pub fn flink<T: AsRef<str>>(fd: usize, path: T) -> Result<usize> {
72 let path = path.as_ref();
73 unsafe { syscall3(SYS_FLINK, fd, path.as_ptr() as usize, path.len()) }
74}
75
76pub fn frename<T: AsRef<str>>(fd: usize, path: T) -> Result<usize> {
78 let path = path.as_ref();
79 unsafe { syscall3(SYS_FRENAME, fd, path.as_ptr() as usize, path.len()) }
80}
81
82pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
84 unsafe {
85 syscall3(
86 SYS_FSTAT,
87 fd,
88 stat as *mut Stat as usize,
89 mem::size_of::<Stat>(),
90 )
91 }
92}
93
94pub fn fstatvfs(fd: usize, stat: &mut StatVfs) -> Result<usize> {
96 unsafe {
97 syscall3(
98 SYS_FSTATVFS,
99 fd,
100 stat as *mut StatVfs as usize,
101 mem::size_of::<StatVfs>(),
102 )
103 }
104}
105
106pub fn fsync(fd: usize) -> Result<usize> {
108 unsafe { syscall1(SYS_FSYNC, fd) }
109}
110
111pub fn ftruncate(fd: usize, len: usize) -> Result<usize> {
113 unsafe { syscall2(SYS_FTRUNCATE, fd, len) }
114}
115
116pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result<usize> {
118 unsafe {
119 syscall3(
120 SYS_FUTIMENS,
121 fd,
122 times.as_ptr() as usize,
123 mem::size_of_val(times),
124 )
125 }
126}
127
128pub unsafe fn futex(
130 addr: *mut i32,
131 op: usize,
132 val: i32,
133 val2: usize,
134 addr2: *mut i32,
135) -> Result<usize> {
136 syscall5(
137 SYS_FUTEX,
138 addr as usize,
139 op,
140 (val as isize) as usize,
141 val2,
142 addr2 as usize,
143 )
144}
145
146pub fn lseek(fd: usize, offset: isize, whence: usize) -> Result<usize> {
148 unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) }
149}
150
151pub fn mkns(schemes: &[[usize; 2]]) -> Result<usize> {
153 unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) }
154}
155
156pub unsafe fn mprotect(addr: usize, size: usize, flags: MapFlags) -> Result<usize> {
158 syscall3(SYS_MPROTECT, addr, size, flags.bits())
159}
160
161pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result<usize> {
163 unsafe {
164 syscall2(
165 SYS_NANOSLEEP,
166 req as *const TimeSpec as usize,
167 rem as *mut TimeSpec as usize,
168 )
169 }
170}
171
172pub fn openat_into<T: AsRef<str>>(
174 fd: usize,
175 out: usize,
176 path: T,
177 flags: usize,
178 fcntl_flags: usize,
179) -> Result<usize> {
180 let path = path.as_ref();
181 unsafe {
182 syscall6(
183 SYS_OPENAT_INTO,
184 fd,
185 path.as_ptr() as usize,
186 path.len(),
187 flags,
188 fcntl_flags,
189 out,
190 )
191 }
192}
193
194pub fn unlinkat<T: AsRef<str>>(fd: usize, path: T, flags: usize) -> Result<usize> {
196 let path = path.as_ref();
197 unsafe { syscall4(SYS_UNLINKAT, fd, path.as_ptr() as usize, path.len(), flags) }
198}
199pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
201 unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) }
202}
203
204pub fn write(fd: usize, buf: &[u8]) -> Result<usize> {
219 unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) }
220}
221
222pub fn sched_yield() -> Result<usize> {
226 unsafe { syscall0(SYS_YIELD) }
227}
228
229pub trait Call {
230 unsafe fn raw_call(
231 &self,
232 payload_ptr: *const u8,
233 len: usize,
234 flags: CallFlags,
235 metadata: &[u64],
236 ) -> Result<usize>;
237}
238
239impl Call for usize {
240 unsafe fn raw_call(
241 &self,
242 payload_ptr: *const u8,
243 len: usize,
244 flags: CallFlags,
245 metadata: &[u64],
246 ) -> Result<usize> {
247 unsafe {
248 syscall5(
249 SYS_CALL,
250 *self,
251 payload_ptr as usize,
252 len,
253 metadata.len() | flags.bits(),
254 metadata.as_ptr() as usize,
255 )
256 }
257 }
258}
259
260impl Call for &[usize] {
261 unsafe fn raw_call(
262 &self,
263 payload_ptr: *const u8,
264 len: usize,
265 flags: CallFlags,
266 metadata: &[u64],
267 ) -> Result<usize> {
268 let combined_flags = flags | CallFlags::MULTIPLE_FDS;
269 unsafe {
270 syscall6(
271 SYS_CALL,
272 self.as_ptr() as usize,
273 payload_ptr as usize,
274 len,
275 metadata.len() | combined_flags.bits(),
276 metadata.as_ptr() as usize,
277 self.len() * mem::size_of::<usize>(),
278 )
279 }
280 }
281}
282
283pub fn call_ro<T: Call>(
285 fd: T,
286 payload: &mut [u8],
287 flags: CallFlags,
288 metadata: &[u64],
289) -> Result<usize> {
290 unsafe {
291 fd.raw_call(
292 payload.as_mut_ptr(),
293 payload.len(),
294 flags | CallFlags::READ,
295 metadata,
296 )
297 }
298}
299pub fn call_wo<T: Call>(
301 fd: T,
302 payload: &[u8],
303 flags: CallFlags,
304 metadata: &[u64],
305) -> Result<usize> {
306 unsafe {
307 fd.raw_call(
308 payload.as_ptr(),
309 payload.len(),
310 flags | CallFlags::WRITE,
311 metadata,
312 )
313 }
314}
315pub fn call_rw<T: Call>(
317 fd: T,
318 payload: &mut [u8],
319 flags: CallFlags,
320 metadata: &[u64],
321) -> Result<usize> {
322 unsafe {
323 fd.raw_call(
324 payload.as_mut_ptr(),
325 payload.len(),
326 flags | CallFlags::READ | CallFlags::WRITE,
327 metadata,
328 )
329 }
330}
331
332pub fn std_fs_call<T: Call>(fd: T, payload: &mut [u8], metadata: &StdFsCallMeta) -> Result<usize> {
333 call_rw(fd, payload, CallFlags::STD_FS, metadata)
334}