Properly propagate panics

This commit is contained in:
Steven Fackler 2016-10-21 21:52:02 -07:00
parent 9be0aab9ac
commit 58f6d1138a
1 changed files with 11 additions and 8 deletions

View File

@ -1,7 +1,7 @@
use libc::{c_int, c_char, c_void}; use libc::{c_int, c_char, c_void};
use std::any::Any; use std::any::Any;
use std::panic; use std::panic::{self, AssertUnwindSafe};
use std::slice; use std::slice;
/// Wraps a user-supplied callback and a slot for panics thrown inside the callback (while FFI /// Wraps a user-supplied callback and a slot for panics thrown inside the callback (while FFI
@ -42,17 +42,20 @@ pub unsafe extern fn invoke_passwd_cb<F>(buf: *mut c_char,
cb_state: *mut c_void) cb_state: *mut c_void)
-> c_int -> c_int
where F: FnOnce(&mut [c_char]) -> usize { where F: FnOnce(&mut [c_char]) -> usize {
let result = panic::catch_unwind(|| {
// build a `i8` slice to pass to the user callback
let pass_slice = slice::from_raw_parts_mut(buf, size as usize);
let callback = &mut *(cb_state as *mut CallbackState<F>); let callback = &mut *(cb_state as *mut CallbackState<F>);
callback.cb.take().unwrap()(pass_slice) let result = panic::catch_unwind(AssertUnwindSafe(|| {
}); // build a `i8` slice to pass to the user callback
let pass_slice = slice::from_raw_parts_mut(buf, size as usize);
if let Ok(len) = result { callback.cb.take().unwrap()(pass_slice)
return len as c_int; }));
} else {
return 0; match result {
Ok(len) => len as c_int,
Err(err) => {
callback.panic = Some(err);
0
}
} }
} }