diff --git a/src/memfd.rs b/src/memfd.rs index 13d37c1..a19d862 100644 --- a/src/memfd.rs +++ b/src/memfd.rs @@ -1,7 +1,9 @@ use crate::sealing; use rustix::fs::{MemfdFlags, SealFlags}; use std::fs; +use std::process; use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; +use std::path::{PathBuf}; /// A `Memfd` builder, providing advanced options and flags for specifying its behavior. #[derive(Clone, Debug)] @@ -159,6 +161,24 @@ impl Memfd { Self::try_from_fd(file) } + /// + /// Returns the absolute path to the `Memfd` file as a String. + /// The path contains the pid of the current process, so it can be shared with other processes. + /// The path remains valid until the `Memfd` or its `File` is dropped. + /// + pub fn as_path_string(&self) -> String { + format!("/proc/{}/fd/{}", process::id(), self.file.as_raw_fd()) + } + + /// + /// Returns the absolute path to the `Memfd` file as a PathBuf. + /// The path contains the pid of the current process, so it can be shared with other processes. + /// The path remains valid until the `Memfd` or its `File` is dropped. + /// + pub fn as_path_buf(&self) -> PathBuf { + PathBuf::from(self.as_path_string()) + } + /// Return a reference to the backing [`File`]. /// /// [`File`]: fs::File diff --git a/tests/memfd.rs b/tests/memfd.rs index 52b62cd..4075469 100644 --- a/tests/memfd.rs +++ b/tests/memfd.rs @@ -1,6 +1,9 @@ extern crate memfd; use std::fs; +use std::fs::File; +use std::io::{Read, Seek, Write}; use std::os::unix::io::AsRawFd; +use memfd::Memfd; #[test] fn test_memfd_default() { @@ -48,6 +51,40 @@ fn test_memfd_from_into() { .expect_err("unexpected conversion from a non-memfd file"); } +#[test] +fn test_memfd_as_path_string() { + const TEST_CONTENT: &[u8] = b"test_memfd_as_path_string"; + let m0 = create_memfd_with_content(TEST_CONTENT); + let path = m0.as_path_string(); + let test_file = File::open(path).unwrap(); + compare_file(test_file, TEST_CONTENT); +} + +#[test] +fn test_memfd_as_path_buf() { + const TEST_CONTENT: &[u8] = b"test_memfd_as_path_buf"; + let m0 = create_memfd_with_content(TEST_CONTENT); + let path = m0.as_path_buf(); + let test_file = File::open(path).unwrap(); + compare_file(test_file, TEST_CONTENT); +} + +fn create_memfd_with_content(content: &[u8]) -> Memfd { + let opts = memfd::MemfdOptions::default(); + let m0 = opts.create("default").unwrap(); + let mut file = m0.as_file(); + file.write(content).unwrap(); + file.seek(std::io::SeekFrom::Start(0)).unwrap(); + return m0; +} + +fn compare_file(mut file: File, expected_content: &[u8]) { + let mut content = Vec::new(); + file.read_to_end(&mut content).unwrap(); + assert_eq!(content.as_slice(), expected_content) +} + + /// Check if the close-on-exec flag is set for the memfd. pub fn get_close_on_exec(memfd: &memfd::Memfd) -> std::io::Result { let flags = rustix::fs::fcntl_getfd(memfd.as_file())?;