Commit 58f6d113 authored by Steven Fackler's avatar Steven Fackler
Browse files

Properly propagate panics

parent 9be0aab9
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
use libc::{c_int, c_char, c_void};

use std::any::Any;
use std::panic;
use std::panic::{self, AssertUnwindSafe};
use std::slice;

/// 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)
                                         -> c_int
                                         where F: FnOnce(&mut [c_char]) -> usize {
    let result = panic::catch_unwind(|| {
    let callback = &mut *(cb_state as *mut CallbackState<F>);

    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);
        let callback = &mut *(cb_state as *mut CallbackState<F>);

        callback.cb.take().unwrap()(pass_slice)
    });
    }));

    if let Ok(len) = result {
        return len as c_int;
    } else {
        return 0;
    match result {
        Ok(len) => len as c_int,
        Err(err) => {
            callback.panic = Some(err);
            0
        }
    }
}