Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vfs: Buffer names for nul termination #107

Merged
merged 2 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ macro_rules! E {

// See module level comment
E!(EAGAIN);
E!(EINVAL);
E!(ENOMEM);
E!(ENOSPC);
E!(EOVERFLOW);
46 changes: 37 additions & 9 deletions src/vfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,38 @@ use riot_sys::libc;
use crate::error::{NegativeErrorExt, NumericError};
use crate::helpers::{PointerToCStr, SliceToCStr};

#[derive(Copy, Clone, Debug)]
struct NameTooLong;
#[derive(Copy, Clone, Debug)]
struct NameContainsIllegalNull;

impl From<NameTooLong> for NumericError {
fn from(_: NameTooLong) -> NumericError {
crate::error::ENOMEM
}
}

impl From<NameContainsIllegalNull> for NumericError {
fn from(_: NameContainsIllegalNull) -> NumericError {
crate::error::EINVAL
}
}
struct NameNullTerminated(heapless::String<{ riot_sys::VFS_NAME_MAX as usize + 1 }>);

impl NameNullTerminated {
fn new(name: &str) -> Result<Self, NameTooLong> {
let mut buf = heapless::String::new();
buf.push_str(name).map_err(|_| NameTooLong)?;
buf.push_str("\0").map_err(|_| NameTooLong)?;
Ok(NameNullTerminated(buf))
}

fn as_cstr(&self) -> Result<&core::ffi::CStr, NameContainsIllegalNull> {
core::ffi::CStr::from_bytes_with_nul(self.0.as_str().as_bytes())
.map_err(|_| NameContainsIllegalNull)
}
}

/// A file handle
#[derive(Debug)]
pub struct File {
Expand Down Expand Up @@ -57,12 +89,9 @@ pub enum SeekFrom {
impl File {
/// Open a file in read-only mode.
pub fn open(path: &str) -> Result<Self, NumericError> {
let path = NameNullTerminated::new(path)?;
let fileno = unsafe {
riot_sys::vfs_open(
path as *const str as *const libc::c_char,
riot_sys::O_RDONLY as _,
0,
)
riot_sys::vfs_open(path.as_cstr()?.as_ptr() as _, riot_sys::O_RDONLY as _, 0)
}
.negative_to_error()?;
Ok(File {
Expand Down Expand Up @@ -120,11 +149,10 @@ pub struct Dir(riot_sys::vfs_DIR, core::marker::PhantomPinned);

impl Dir {
pub fn open(dir: &str) -> Result<Self, NumericError> {
let dir = NameNullTerminated::new(dir)?;
let mut dirp = MaybeUninit::uninit();
(unsafe {
riot_sys::vfs_opendir(dirp.as_mut_ptr(), dir as *const str as *const libc::c_char)
})
.negative_to_error()?;
(unsafe { riot_sys::vfs_opendir(dirp.as_mut_ptr(), dir.as_cstr()?.as_ptr() as _) })
.negative_to_error()?;
let dirp = unsafe { dirp.assume_init() };
Ok(Dir(dirp, core::marker::PhantomPinned))
}
Expand Down
Loading