Skip to content

Commit ff8933e

Browse files
zephyr: error: helper to convert return code and errno to Result
Various Zephyr functions have a return code where '-1' indicates an error, but the exact error code is stored in the errno variable. Add a helper function to convert this kind of return value into a Result. Signed-off-by: Matt Rodgers <[email protected]>
1 parent 5fd7f84 commit ff8933e

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

main.c

+8
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,12 @@ void rust_panic_wrap(void)
5252
k_panic();
5353
}
5454

55+
/* `errno` is usually defined as a macro rather than a variable, which makes it difficult to
56+
* access in Rust. So create a simple getter function in C.
57+
*/
58+
int get_errno(void)
59+
{
60+
return errno;
61+
}
62+
5563
#endif

zephyr/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ cfg-if = "1.0"
2222
log = "0.4.22"
2323
arrayvec = { version = "0.7.6", default-features = false }
2424

25+
# The num crate is used primarily for the Zero trait bound
26+
num = { version = "0.4", default-features = false }
27+
2528
[dependencies.fugit]
2629
version = "0.3.7"
2730

zephyr/src/error.rs

+20
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@
1111
//! this an enum itself, however, it would probably be better to auto-generate this enum instead of
1212
//! trying to maintain the list manually.
1313
14+
use core::cmp::PartialOrd;
1415
use core::ffi::c_int;
1516
use core::fmt;
17+
use num::Zero;
18+
19+
extern "C" {
20+
fn get_errno() -> c_int;
21+
}
1622

1723
// This is a little messy because the constants end up as u32 from bindgen, although the values are
1824
// negative.
@@ -51,6 +57,20 @@ pub fn to_result(code: c_int) -> Result<c_int> {
5157
}
5258
}
5359

60+
/// Map a return result and errno from Zephyr into a Result.
61+
///
62+
/// Some Zephyr functions (particularly those intended for compatibility with POSIX function
63+
/// signatures) return -1 on error, with the specific error code stored in the `errno` variable.
64+
#[inline(always)]
65+
pub fn to_result_errno<T: PartialOrd + Zero>(code: T) -> Result<T> {
66+
if code < T::zero() {
67+
let e = unsafe { get_errno() };
68+
Err(Error(e as u32))
69+
} else {
70+
Ok(code)
71+
}
72+
}
73+
5474
/// Map a return result, with a void result.
5575
#[inline(always)]
5676
pub fn to_result_void(code: c_int) -> Result<()> {

0 commit comments

Comments
 (0)