Skip to content

Commit

Permalink
Handle platforms where c_int is not i32
Browse files Browse the repository at this point in the history
Some functions assume that c_int is always i32.  This is not true for
all platforms.  This patch adapts those functions to handle those cases.

Some littlefs functions return an error code (c_int) from functions
returning i32.  In these cases, error codes are truncated to c_int::MIN.
  • Loading branch information
robin-nitrokey committed Aug 16, 2024
1 parent d665899 commit 2544bd1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added `Filesystem::mount_or_else` function ([#57][])
- Marked `Path::is_empty`, `Path::from_bytes_with_nul`, `Path::from_cstr`, `Path::from_cstr_unchecked`, `Path::as_str_ref_with_trailing_nul`, `Path::as_str`, and `PathBuf::new` as `const`.
- Made `fs::FileOpenFlags` public and added `From<fs::FileOpenFlags>` for `fs::OpenOptions`.
- Support platforms where `c_int` is not `i32`.

### Fixed

Expand Down
44 changes: 27 additions & 17 deletions src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ fn result_from<T>(return_value: T, error_code: ll::lfs_error) -> Result<T> {
}
}

pub fn u32_result(return_value: i32) -> Result<u32> {
u32::try_from(return_value).map_err(|_| {
let error_code = c_int::try_from(return_value).unwrap_or(c_int::MIN);
Error::new(error_code).unwrap()
})
}

struct Cache<Storage: driver::Storage> {
read: UnsafeCell<Bytes<Storage::CACHE_SIZE>>,
write: UnsafeCell<Bytes<Storage::CACHE_SIZE>>,
Expand Down Expand Up @@ -247,7 +254,9 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
/// by this method available, at any given time.
pub fn available_blocks(&self) -> Result<usize> {
let return_code = unsafe { ll::lfs_fs_size(&mut self.alloc.borrow_mut().state) };
result_from(return_code, return_code).map(|blocks| self.total_blocks() - blocks as usize)
u32_result(return_code)
.map(|blocks| usize::try_from(blocks).unwrap_or(usize::MAX))
.map(|blocks| self.total_blocks().saturating_sub(blocks))
}

/// Available number of unused bytes in the filesystem
Expand Down Expand Up @@ -430,17 +439,18 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
)
};

if return_code >= 0 {
attribute.set_size(return_code as usize);
return Ok(Some(attribute));
}
if return_code == ll::lfs_error_LFS_ERR_NOATTR {
return Ok(None);
}

result_from((), return_code)?;
// TODO: get rid of this
unreachable!();
u32_result(return_code)
.map(|n| {
attribute.set_size(n as usize);
Some(attribute)
})
.or_else(|err| {
if err == Error::NO_ATTRIBUTE {
Ok(None)
} else {
Err(err)
}
})
}

/// Remove attribute.
Expand Down Expand Up @@ -516,7 +526,7 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {

/// C callback interface used by LittleFS to sync data with the lower level interface below the
/// filesystem. Note that this function currently does nothing.
extern "C" fn lfs_config_sync(_c: *const ll::lfs_config) -> i32 {
extern "C" fn lfs_config_sync(_c: *const ll::lfs_config) -> c_int {
// println!("in lfs_config_sync");
// Do nothing; we presume that data is synchronized.
0
Expand Down Expand Up @@ -653,7 +663,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage> {
addr_of_mut!((*(*self.alloc.borrow_mut())).state),
)
};
result_from(return_code as usize, return_code)
u32_result(return_code).map(|n| n as usize)
}

pub fn is_empty(&self) -> Result<bool> {
Expand Down Expand Up @@ -860,7 +870,7 @@ impl<S: driver::Storage> io::Read for File<'_, '_, S> {
buf.len() as u32,
)
};
result_from(return_code as usize, return_code)
u32_result(return_code).map(|n| n as usize)
}
}

Expand All @@ -877,7 +887,7 @@ impl<S: driver::Storage> io::Seek for File<'_, '_, S> {
pos.whence(),
)
};
result_from(return_code as usize, return_code)
u32_result(return_code).map(|n| n as usize)
}
}

Expand All @@ -894,7 +904,7 @@ impl<S: driver::Storage> io::Write for File<'_, '_, S> {
buf.len() as u32,
)
};
result_from(return_code as usize, return_code)
u32_result(return_code).map(|n| n as usize)
}

fn flush(&self) -> Result<()> {
Expand Down

0 comments on commit 2544bd1

Please sign in to comment.