diff --git a/CHANGELOG.md b/CHANGELOG.md index a308c6ae..8f84f39d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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` for `fs::OpenOptions`. +- Support platforms where `c_int` is not `i32`. ### Fixed diff --git a/src/fs.rs b/src/fs.rs index 207afa69..170be3b8 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -35,6 +35,13 @@ fn result_from(return_value: T, error_code: ll::lfs_error) -> Result { } } +pub fn u32_result(return_value: i32) -> Result { + 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 { read: UnsafeCell>, write: UnsafeCell>, @@ -247,7 +254,9 @@ impl Filesystem<'_, Storage> { /// by this method available, at any given time. pub fn available_blocks(&self) -> Result { 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 @@ -430,17 +439,18 @@ impl 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. @@ -516,7 +526,7 @@ impl 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 @@ -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 { @@ -860,7 +870,7 @@ impl 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) } } @@ -877,7 +887,7 @@ impl io::Seek for File<'_, '_, S> { pos.whence(), ) }; - result_from(return_code as usize, return_code) + u32_result(return_code).map(|n| n as usize) } } @@ -894,7 +904,7 @@ impl 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<()> {