Wrap create_memfd() system call and manage memfd file descriptors
This commit is contained in:
parent
f47eff5ef8
commit
9b2e7b8837
76
rust/src/system/memfd.rs
Normal file
76
rust/src/system/memfd.rs
Normal file
@ -0,0 +1,76 @@
|
||||
use std::ffi::CString;
|
||||
use std::io::SeekFrom;
|
||||
use std::os::unix::io::{RawFd,AsRawFd};
|
||||
|
||||
use crate::system::{Result, FileDesc, errno_result};
|
||||
|
||||
use libc::{
|
||||
self, c_char, c_uint, c_int, c_long,SYS_memfd_create,
|
||||
MFD_CLOEXEC, MFD_ALLOW_SEALING, F_SEAL_GROW,F_SEAL_SHRINK, F_SEAL_SEAL
|
||||
};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MemoryFd {
|
||||
fd: FileDesc,
|
||||
size: usize,
|
||||
}
|
||||
|
||||
impl MemoryFd {
|
||||
|
||||
pub fn from_filedesc(fd: FileDesc) -> Result<MemoryFd> {
|
||||
let size = fd.seek(SeekFrom::End(0))? as usize;
|
||||
Ok(MemoryFd { fd, size })
|
||||
}
|
||||
|
||||
pub fn new_memfd(size: usize, sealed: bool) -> Result<MemoryFd> {
|
||||
Self::new_memfd_with_name(size, sealed, "pH-memfd")
|
||||
}
|
||||
|
||||
pub fn new_memfd_with_name(size: usize, sealed: bool, name: &str) -> Result<MemoryFd> {
|
||||
let fd = Self::memfd_create(name, MFD_CLOEXEC | MFD_ALLOW_SEALING)?;
|
||||
fd.set_size(size)?;
|
||||
|
||||
let memfd = MemoryFd { fd, size };
|
||||
if sealed {
|
||||
memfd.add_seals(F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL)?;
|
||||
}
|
||||
|
||||
Ok(memfd)
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
self.size
|
||||
}
|
||||
|
||||
pub fn fd_mut(&mut self) -> &mut FileDesc {
|
||||
&mut self.fd
|
||||
}
|
||||
|
||||
fn memfd_create(name: &str, flags: c_uint) -> Result<FileDesc> {
|
||||
let name = CString::new(name).expect("Cstring from &str");
|
||||
let name = name.as_ptr() as *const c_char;
|
||||
let fd = unsafe { libc::syscall(SYS_memfd_create as c_long, name, flags) } as c_int;
|
||||
if fd < 0 {
|
||||
errno_result()
|
||||
} else {
|
||||
Ok(FileDesc::new(fd))
|
||||
}
|
||||
}
|
||||
|
||||
fn add_seals(&self, flags: c_int) -> Result<()> {
|
||||
let ret = unsafe { libc::fcntl(self.fd.as_raw_fd(), libc::F_ADD_SEALS, flags) };
|
||||
if ret < 0 {
|
||||
errno_result()
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl AsRawFd for MemoryFd {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.fd.as_raw_fd()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user