use std::fs::File;
use std::io::{Error, Result};
use std::mem::MaybeUninit;
use std::os::fd::{AsRawFd, FromRawFd};
use std::ptr::NonNull;
use std::slice;
use libc::epoll_event;
use super::Attr;
pub fn perf_event_open(attr: &Attr, pid: i32, cpu: i32, group_fd: i32, flags: u64) -> Result<File> {
let num = libc::SYS_perf_event_open;
let fd = unsafe { libc::syscall(num, attr, pid, cpu, group_fd, flags) };
if fd != -1 {
Ok(unsafe { File::from_raw_fd(fd as _) })
} else {
Err(Error::last_os_error())
}
}
pub unsafe fn ioctl_arg(file: &File, op: u64, arg: u64) -> Result<i32> {
let fd = file.as_raw_fd();
let result = unsafe { libc::ioctl(fd, op as _, arg) };
if result != -1 {
Ok(result)
} else {
Err(Error::last_os_error())
}
}
pub fn read(file: &File, buf: &mut [u8]) -> Result<usize> {
let fd = file.as_raw_fd();
let count = buf.len();
let buf = buf.as_mut_ptr() as _;
let bytes = unsafe { libc::read(fd, buf, count) };
if bytes != -1 {
Ok(bytes as _)
} else {
Err(Error::last_os_error())
}
}
pub unsafe fn mmap(
ptr: *mut (),
len: usize,
prot: i32,
flags: i32,
file: &File,
offset: i64,
) -> Result<NonNull<()>> {
let fd = file.as_raw_fd();
let ptr = libc::mmap(ptr as _, len, prot, flags, fd, offset);
if ptr != libc::MAP_FAILED {
Ok(unsafe { NonNull::new_unchecked(ptr as _) })
} else {
Err(Error::last_os_error())
}
}
pub unsafe fn munmap(ptr: *mut (), len: usize) -> Result<()> {
let result = libc::munmap(ptr as _, len);
if result != -1 {
Ok(())
} else {
Err(Error::last_os_error())
}
}
pub fn epoll_create1(flags: i32) -> Result<File> {
let fd = unsafe { libc::epoll_create1(flags) };
if fd != -1 {
Ok(unsafe { File::from_raw_fd(fd as _) })
} else {
Err(Error::last_os_error())
}
}
pub fn epoll_ctl(epoll: &File, op: i32, file: &File, event: &mut epoll_event) -> Result<()> {
let epfd = epoll.as_raw_fd();
let fd = file.as_raw_fd();
let result = unsafe { libc::epoll_ctl(epfd, op, fd, event as _) };
if result != -1 {
Ok(())
} else {
Err(Error::last_os_error())
}
}
pub fn epoll_wait<'a>(
epoll: &File,
events: &'a mut [MaybeUninit<epoll_event>],
timeout: i32,
) -> Result<&'a [epoll_event]> {
let epfd = epoll.as_raw_fd();
let events_ptr = events.as_mut_ptr() as *mut _;
let events_len = events.len();
let len = unsafe { libc::epoll_wait(epfd, events_ptr, events_len as _, timeout) };
if len != -1 {
Ok(unsafe { slice::from_raw_parts(events_ptr, len as _) })
} else {
Err(Error::last_os_error())
}
}
pub fn eventfd(initval: u32, flags: i32) -> Result<File> {
let fd = unsafe { libc::eventfd(initval, flags) };
if fd != -1 {
Ok(unsafe { File::from_raw_fd(fd as _) })
} else {
Err(Error::last_os_error())
}
}
pub fn eventfd_write(event: &File, value: u64) -> Result<()> {
let result = unsafe { libc::eventfd_write(event.as_raw_fd(), value) };
if result == 0 {
Ok(())
} else {
Err(Error::last_os_error())
}
}
pub fn prctl(option: i32) -> Result<()> {
let result = unsafe { libc::prctl(option) };
if result != -1 {
Ok(())
} else {
Err(Error::last_os_error())
}
}