rust-lang / libc

Raw bindings to platform APIs for Rust
https://docs.rs/libc
Apache License 2.0
2.08k stars 1.04k forks source link

setjmp/longjmp #1208

Open jeff-davis opened 5 years ago

jeff-davis commented 5 years ago

I would like support for setjmp/longjmp (and friends sigsetjmp/siglongjmp). The use case is as follows:

I am trying to integrate with postgres (written in C), which means calling into postgres functions. The postgres exception mechanism uses sigsetjmp/siglongjmp.

The idea is, right before calling a postgres function via FFI call, I would do what postgres does in its PG_TRY() / PG_CATCH() macros, which involves sigsetjmp() and some local variable manipulation, and updating a global pointer. That would allow me to catch the siglongjmp() before it bypasses any rust frames, turn it into a rust panic, and properly unwind.

Later, before returning to postgres, I could catch this panic unwind in the highest rust frame, and turn it back into a siglongjmp(). I could be careful that all non-trivial variables have gone out of scope before the siglongjmp() takes place, so that no important destructors are skipped.

If this is a reasonable thing to do, I'd be willing to try to implement it for the libc crate and offer a patch, though I may need some help getting the platform stuff right (because the jmp_buf struct size is platform-dependent).

If it's not a reasonable thing to do, please let me know.

alexcrichton commented 5 years ago

Seems reasonable to me to add!