Skip to content

Commit 895e4cf

Browse files
authored
refactor(ffi): return null ptr instead of aborting in C API (#2478)
Make C API functions that return pointers return null in case of a panic, instead of aborting. Add ffi_fn! macro rules that enable default error values to be returned by writing "?= <value>" after an ffi function's body.
1 parent 68d4e4a commit 895e4cf

File tree

7 files changed

+33
-25
lines changed

7 files changed

+33
-25
lines changed

src/ffi/body.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ ffi_fn! {
3434
/// If not configured, this body acts as an empty payload.
3535
fn hyper_body_new() -> *mut hyper_body {
3636
Box::into_raw(Box::new(hyper_body(Body::empty())))
37-
}
37+
} ?= ptr::null_mut()
3838
}
3939

4040
ffi_fn! {
@@ -66,7 +66,7 @@ ffi_fn! {
6666
Box::into_raw(hyper_task::boxed(async move {
6767
body.0.data().await.map(|res| res.map(hyper_buf))
6868
}))
69-
}
69+
} ?= ptr::null_mut()
7070
}
7171

7272
ffi_fn! {
@@ -97,7 +97,7 @@ ffi_fn! {
9797
}
9898
Ok(())
9999
}))
100-
}
100+
} ?= ptr::null_mut()
101101
}
102102

103103
ffi_fn! {
@@ -198,7 +198,7 @@ ffi_fn! {
198198
std::slice::from_raw_parts(buf, len)
199199
};
200200
Box::into_raw(Box::new(hyper_buf(Bytes::copy_from_slice(slice))))
201-
}
201+
} ?= ptr::null_mut()
202202
}
203203

204204
ffi_fn! {
@@ -211,7 +211,7 @@ ffi_fn! {
211211
/// consumed/freed.
212212
fn hyper_buf_bytes(buf: *const hyper_buf) -> *const u8 {
213213
unsafe { (*buf).0.as_ptr() }
214-
}
214+
} ?= ptr::null()
215215
}
216216

217217
ffi_fn! {

src/ffi/client.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ ffi_fn! {
5757
hyper_clientconn { tx }
5858
})
5959
}))
60-
}
60+
} ?= std::ptr::null_mut()
6161
}
6262

6363
ffi_fn! {
@@ -85,7 +85,7 @@ ffi_fn! {
8585
};
8686

8787
Box::into_raw(hyper_task::boxed(fut))
88-
}
88+
} ?= std::ptr::null_mut()
8989
}
9090

9191
ffi_fn! {
@@ -110,7 +110,7 @@ ffi_fn! {
110110
builder: conn::Builder::new(),
111111
exec: WeakExec::new(),
112112
}))
113-
}
113+
} ?= std::ptr::null_mut()
114114
}
115115

116116
ffi_fn! {

src/ffi/http_types.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ ffi_fn! {
3737
/// Construct a new HTTP request.
3838
fn hyper_request_new() -> *mut hyper_request {
3939
Box::into_raw(Box::new(hyper_request(Request::new(Body::empty()))))
40-
}
40+
} ?= std::ptr::null_mut()
4141
}
4242

4343
ffi_fn! {
@@ -114,7 +114,7 @@ ffi_fn! {
114114
/// `hyper_request` has been consumed.
115115
fn hyper_request_headers(req: *mut hyper_request) -> *mut hyper_headers {
116116
hyper_headers::get_or_default(unsafe { &mut *req }.0.extensions_mut())
117-
}
117+
} ?= std::ptr::null_mut()
118118
}
119119

120120
ffi_fn! {
@@ -170,7 +170,7 @@ ffi_fn! {
170170
/// buffer.
171171
fn hyper_response_reason_phrase(resp: *const hyper_response) -> *const u8 {
172172
unsafe { &*resp }.reason_phrase().as_ptr()
173-
}
173+
} ?= std::ptr::null()
174174
}
175175

176176
ffi_fn! {
@@ -210,7 +210,7 @@ ffi_fn! {
210210
/// `hyper_response` has been freed.
211211
fn hyper_response_headers(resp: *mut hyper_response) -> *mut hyper_headers {
212212
hyper_headers::get_or_default(unsafe { &mut *resp }.0.extensions_mut())
213-
}
213+
} ?= std::ptr::null_mut()
214214
}
215215

216216
ffi_fn! {
@@ -220,7 +220,7 @@ ffi_fn! {
220220
fn hyper_response_body(resp: *mut hyper_response) -> *mut hyper_body {
221221
let body = std::mem::take(unsafe { &mut *resp }.0.body_mut());
222222
Box::into_raw(Box::new(hyper_body(body)))
223-
}
223+
} ?= std::ptr::null_mut()
224224
}
225225

226226
impl hyper_response {

src/ffi/io.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ ffi_fn! {
3737
write: write_noop,
3838
userdata: std::ptr::null_mut(),
3939
}))
40-
}
40+
} ?= std::ptr::null_mut()
4141
}
4242

4343
ffi_fn! {

src/ffi/macros.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
macro_rules! ffi_fn {
2-
($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty $body:block) => {
2+
($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty $body:block ?= $default:expr) => {
33
$(#[$doc])*
44
#[no_mangle]
55
pub extern fn $name($($arg: $arg_ty),*) -> $ret {
@@ -8,15 +8,23 @@ macro_rules! ffi_fn {
88
match panic::catch_unwind(AssertUnwindSafe(move || $body)) {
99
Ok(v) => v,
1010
Err(_) => {
11-
// TODO: We shouldn't abort, but rather figure out how to
12-
// convert into the return type that the function errored.
13-
eprintln!("panic unwind caught, aborting");
14-
std::process::abort();
11+
$default
1512
}
1613
}
1714
}
1815
};
1916

17+
($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty $body:block) => {
18+
ffi_fn!($(#[$doc])* fn $name($($arg: $arg_ty),*) -> $ret $body ?= {
19+
eprintln!("panic unwind caught, aborting");
20+
std::process::abort()
21+
});
22+
};
23+
24+
($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) $body:block ?= $default:expr) => {
25+
ffi_fn!($(#[$doc])* fn $name($($arg: $arg_ty),*) -> () $body ?= $default);
26+
};
27+
2028
($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) $body:block) => {
2129
ffi_fn!($(#[$doc])* fn $name($($arg: $arg_ty),*) -> () $body);
2230
};

src/ffi/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,5 @@ ffi_fn! {
9292
/// Returns a static ASCII (null terminated) string of the hyper version.
9393
fn hyper_version() -> *const libc::c_char {
9494
VERSION_CSTR.as_ptr() as _
95-
}
95+
} ?= std::ptr::null()
9696
}

src/ffi/task.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ ffi_fn! {
189189
/// Creates a new task executor.
190190
fn hyper_executor_new() -> *const hyper_executor {
191191
Arc::into_raw(hyper_executor::new())
192-
}
192+
} ?= ptr::null()
193193
}
194194

195195
ffi_fn! {
@@ -230,7 +230,7 @@ ffi_fn! {
230230
Some(task) => Box::into_raw(task),
231231
None => ptr::null_mut(),
232232
}
233-
}
233+
} ?= ptr::null_mut()
234234
}
235235

236236
// ===== impl hyper_task =====
@@ -303,7 +303,7 @@ ffi_fn! {
303303
} else {
304304
ptr::null_mut()
305305
}
306-
}
306+
} ?= ptr::null_mut()
307307
}
308308

309309
ffi_fn! {
@@ -341,7 +341,7 @@ ffi_fn! {
341341
}
342342

343343
unsafe { &*task }.userdata.0
344-
}
344+
} ?= ptr::null_mut()
345345
}
346346

347347
// ===== impl AsTaskType =====
@@ -405,7 +405,7 @@ ffi_fn! {
405405
fn hyper_context_waker(cx: *mut hyper_context<'_>) -> *mut hyper_waker {
406406
let waker = unsafe { &mut *cx }.0.waker().clone();
407407
Box::into_raw(Box::new(hyper_waker { waker }))
408-
}
408+
} ?= ptr::null_mut()
409409
}
410410

411411
// ===== impl hyper_waker =====

0 commit comments

Comments
 (0)