shadow_shmem/
raw_syscall.rs
1use linux_api::errno::Errno;
16use linux_syscall::Result as LinuxSyscallResult;
17use linux_syscall::syscall;
18
19pub const S_IRUSR: u32 = 0o400;
20pub const S_IWUSR: u32 = 0o200;
21pub const S_IRGRP: u32 = S_IRUSR >> 3;
22pub const S_IWGRP: u32 = S_IWUSR >> 3;
23
24fn null_terminated(string: &[u8]) -> bool {
25 string.iter().any(|x| *x == 0)
26}
27
28pub unsafe fn open(
33 filename: &[u8],
34 flags: linux_api::fcntl::OFlag,
35 mode: u32,
36) -> Result<i32, Errno> {
37 assert!(null_terminated(filename));
38
39 let rc = unsafe {
40 syscall!(
41 linux_syscall::SYS_open,
42 filename.as_ptr(),
43 flags.bits(),
44 mode
45 )
46 };
47
48 rc.check().map_err(Errno::from)?;
49
50 Ok(rc.as_u64_unchecked() as i32)
51}
52
53pub fn close(fd: i32) -> Result<(), Errno> {
54 unsafe { syscall!(linux_syscall::SYS_close, fd) }
55 .check()
56 .map_err(Errno::from)
57}
58
59pub unsafe fn unlink(filename: &[u8]) -> Result<(), Errno> {
63 assert!(null_terminated(filename));
64
65 unsafe { syscall!(linux_syscall::SYS_unlink, filename.as_ptr()) }
66 .check()
67 .map_err(Errno::from)
68}
69
70pub unsafe fn mmap<'a>(
75 addr: *mut core::ffi::c_void,
76 length: u64,
77 prot: linux_api::mman::ProtFlags,
78 flags: linux_api::mman::MapFlags,
79 fd: i32,
80 offset: u64,
81) -> Result<&'a mut [u8], Errno> {
82 let rc = unsafe {
83 syscall!(
84 linux_syscall::SYS_mmap,
85 addr,
86 length,
87 prot.bits(),
88 flags.bits(),
89 fd,
90 offset
91 )
92 };
93
94 rc.check().map_err(Errno::from)?;
95
96 let rc = rc.as_u64_unchecked();
97
98 Ok(unsafe { core::slice::from_raw_parts_mut(rc as *mut u8, length.try_into().unwrap()) })
99}
100
101pub fn munmap(bytes: &mut [u8]) -> Result<(), Errno> {
102 unsafe { syscall!(linux_syscall::SYS_munmap, bytes.as_mut_ptr(), bytes.len()) }
103 .check()
104 .map_err(Errno::from)
105}
106
107pub fn ftruncate(fd: i32, nbytes: u64) -> Result<(), Errno> {
108 unsafe { syscall!(linux_syscall::SYS_ftruncate, fd, nbytes) }
109 .check()
110 .map_err(Errno::from)
111}
112
113pub fn clock_monotonic_gettime() -> Result<linux_api::time::timespec, Errno> {
114 let cm: i32 = linux_api::time::ClockId::CLOCK_MONOTONIC.into();
115
116 let mut ts = linux_api::time::timespec {
117 tv_sec: 0,
118 tv_nsec: 0,
119 };
120
121 let rc = unsafe { syscall!(linux_syscall::SYS_clock_gettime, cm, &mut ts) };
122
123 rc.check().map_err(Errno::from)?;
124
125 Ok(ts)
126}
127
128pub fn getpid() -> Result<i32, Errno> {
129 let rc = unsafe { syscall!(linux_syscall::SYS_getpid) };
130
131 rc.check().map_err(Errno::from)?;
132
133 Ok(rc.as_u64_unchecked() as i32)
134}
135
136pub fn gettid() -> Result<i32, Errno> {
137 let rc = unsafe { syscall!(linux_syscall::SYS_gettid) };
138
139 rc.check().map_err(Errno::from)?;
140
141 Ok(rc.as_u64_unchecked() as i32)
142}
143
144pub fn kill(pid: i32, signal: i32) -> Result<(), Errno> {
145 unsafe { syscall!(linux_syscall::SYS_kill, pid, signal) }
146 .check()
147 .map_err(Errno::from)
148}
149
150pub fn tgkill(pid: i32, tid: i32, signal: i32) -> Result<(), Errno> {
151 unsafe { syscall!(linux_syscall::SYS_tgkill, pid, tid, signal) }
152 .check()
153 .map_err(Errno::from)
154}
155
156pub fn fsync(fd: i32) -> Result<(), Errno> {
157 unsafe { syscall!(linux_syscall::SYS_fsync, fd) }
158 .check()
159 .map_err(Errno::from)
160}
161
162pub unsafe fn write(fd: i32, buf: *const core::ffi::c_void, count: usize) -> Result<isize, Errno> {
166 let rc = unsafe { syscall!(linux_syscall::SYS_write, fd, buf, count) };
167 rc.check().map_err(Errno::from)?;
168 Ok(rc.as_u64_unchecked() as isize)
169}