]>
git.proxmox.com Git - cargo.git/blob - vendor/openssl-0.9.23/src/util.rs
1 use libc
::{c_int, c_char, c_void}
;
3 use std
::panic
::{self, AssertUnwindSafe}
;
8 /// Wraps a user-supplied callback and a slot for panics thrown inside the callback (while FFI
9 /// frames are on the stack).
11 /// When dropped, checks if the callback has panicked, and resumes unwinding if so.
12 pub struct CallbackState
<F
> {
13 /// The user callback. Taken out of the `Option` when called.
15 /// If the callback panics, we place the panic object here, to be re-thrown once OpenSSL
17 panic
: Option
<Box
<Any
+ Send
+ '
static>>,
20 impl<F
> CallbackState
<F
> {
21 pub fn new(callback
: F
) -> Self {
29 impl<F
> Drop
for CallbackState
<F
> {
31 if let Some(panic
) = self.panic
.take() {
32 panic
::resume_unwind(panic
);
37 pub unsafe extern "C" fn invoke_passwd_cb_old
<F
>(
41 cb_state
: *mut c_void
,
44 F
: FnOnce(&mut [c_char
]) -> usize,
46 let callback
= &mut *(cb_state
as *mut CallbackState
<F
>);
48 let result
= panic
::catch_unwind(AssertUnwindSafe(|| {
49 let pass_slice
= slice
::from_raw_parts_mut(buf
, size
as usize);
50 callback
.cb
.take().unwrap()(pass_slice
)
54 Ok(len
) => len
as c_int
,
56 callback
.panic
= Some(err
);
62 /// Password callback function, passed to private key loading functions.
64 /// `cb_state` is expected to be a pointer to a `CallbackState`.
65 pub unsafe extern "C" fn invoke_passwd_cb
<F
>(
69 cb_state
: *mut c_void
,
72 F
: FnOnce(&mut [u8]) -> Result
<usize, ErrorStack
>,
74 let callback
= &mut *(cb_state
as *mut CallbackState
<F
>);
76 let result
= panic
::catch_unwind(AssertUnwindSafe(|| {
77 let pass_slice
= slice
::from_raw_parts_mut(buf
as *mut u8, size
as usize);
78 callback
.cb
.take().unwrap()(pass_slice
)
82 Ok(Ok(len
)) => len
as c_int
,
84 // FIXME restore error stack
88 callback
.panic
= Some(err
);