summaryrefslogtreecommitdiffhomepage
path: root/src/platform/linux/libc_s.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/linux/libc_s.rs')
-rw-r--r--src/platform/linux/libc_s.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/platform/linux/libc_s.rs b/src/platform/linux/libc_s.rs
new file mode 100644
index 0000000..f599ed0
--- /dev/null
+++ b/src/platform/linux/libc_s.rs
@@ -0,0 +1,95 @@
+// SPDX-FileCopyrightText: 2026 Dilluti0n <[email protected]>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+use std::os::fd::{OwnedFd, RawFd, FromRawFd};
+use std::io::Error;
+
+use std::ffi::{c_int, c_void};
+use std::mem;
+
+macro_rules! syscall {
+ ($call:expr) => {
+ match $call {
+ -1 => Err(::std::io::Error::last_os_error()),
+ res => Ok(res),
+ }
+ };
+}
+
+#[allow(non_camel_case_types)]
+pub enum FcntlArg {
+ F_GETFL,
+ F_SETFL(c_int),
+}
+
+pub fn fcntl(fd: RawFd, op: FcntlArg) -> Result<c_int, Error> {
+ use libc::fcntl;
+
+ syscall!(match op {
+ FcntlArg::F_GETFL => unsafe { fcntl(fd, libc::F_GETFL) },
+ FcntlArg::F_SETFL(flags) => unsafe { fcntl(fd, libc::F_SETFL, flags) }
+ })
+}
+
+pub fn flock(fd: RawFd, op: c_int) -> Result<(), Error> {
+ syscall!(unsafe { libc::flock(fd, op) }).map(drop)
+}
+
+pub fn geteuid() -> libc::uid_t {
+ unsafe { libc::geteuid() }
+}
+
+pub fn poll(fds: &mut [libc::pollfd], timeout: c_int) -> Result<(), Error> {
+ syscall!(unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as _, timeout) }).map(drop)
+}
+
+unsafe fn setsockopt_1<T>(sockfd: RawFd, level: c_int, optname: c_int, optval: &T) -> c_int {
+ unsafe {
+ libc::setsockopt(sockfd, level, optname,
+ (optval as *const T).cast() as *const c_void,
+ mem::size_of::<T>() as libc::socklen_t)
+ }
+}
+
+#[allow(non_camel_case_types)]
+pub enum SockOpt<'a> {
+ SO_ATTACH_FILTER(&'a [libc::sock_filter]),
+ PACKET_RX_RING(&'a libc::tpacket_req),
+}
+
+pub fn setsockopt(sockfd: RawFd, opt: SockOpt) -> Result<(), Error> {
+ syscall!(match opt {
+ SockOpt::SO_ATTACH_FILTER(val) => {
+ let prog = libc::sock_fprog {
+ len: val.len() as u16,
+ filter: val.as_ptr() as *mut libc::sock_filter
+ };
+
+ unsafe {setsockopt_1(sockfd, libc::SOL_SOCKET, libc::SO_ATTACH_FILTER, &prog)}
+ },
+ SockOpt::PACKET_RX_RING(optval) => unsafe {
+ setsockopt_1(sockfd, libc::SOL_PACKET, libc::PACKET_RX_RING, optval)
+ }
+ }).map(drop)
+}
+
+pub fn socket(domain: c_int, so_type: c_int, protocol: c_int) -> Result<OwnedFd, Error> {
+ unsafe {
+ let raw = syscall!(libc::socket(domain, so_type, protocol))?;
+ Ok(OwnedFd::from_raw_fd(raw))
+ }
+}
+
+pub unsafe fn mmap(
+ addr: *mut c_void, length: usize, prot: c_int,
+ flags: c_int, fd: RawFd, offset: libc::off_t
+) -> Result<*mut c_void, Error> {
+ match unsafe {libc::mmap(addr, length, prot, flags, fd, offset)} {
+ libc::MAP_FAILED => Err(Error::last_os_error()),
+ res => Ok(res),
+ }
+}
+
+pub unsafe fn munmap(addr: *mut c_void, length: usize) -> Result<(), Error> {
+ syscall!(unsafe { libc::munmap(addr, length) }).map(drop)
+}