diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-01-17 11:11:27 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-01-17 16:48:28 +0100 |
commit | 3f58832474a4b270e136544016a401ef773ac065 (patch) | |
tree | c617160250c3040ca964c1b72ab5957cd872b82f /openpgp-ffi/src/lib.rs | |
parent | 38b4108cc1eac851ac17932c5c33623dd535bebb (diff) |
openpgp-ffi: New crate.
- This creates a new crate, 'sequoia-openpgp-ffi', and moves a
handful of functions from 'sequoia-ffi' to it.
- The 'sequoia-ffi' crate is a superset of the 'sequoia-openpgp-ffi'
crate. This is accomplished by some include! magic.
- My first attempt involved having 'sequoia-ffi' depend on
'sequoia-openpgp-ffi', so that the former just re-exports the
symbols. However, that turned out to be unreliable, and might be
not what we want, because it could also duplicate parts of Rust's
standard library.
- Fixes #144.
Diffstat (limited to 'openpgp-ffi/src/lib.rs')
-rw-r--r-- | openpgp-ffi/src/lib.rs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/openpgp-ffi/src/lib.rs b/openpgp-ffi/src/lib.rs new file mode 100644 index 00000000..40233a37 --- /dev/null +++ b/openpgp-ffi/src/lib.rs @@ -0,0 +1,118 @@ +//! Provides a Foreign Function Interface. +//! +//! We provide a set of functions that use C types and the C calling +//! convention. This interfaces allows you to use Sequoia safely from +//! any other language. +//! +//! # Guarantees +//! +//! Provided that the caller obeys her side of the contract, this +//! library... +//! +//! - will not make an invalid memory access, +//! - will not `abort(2)`, +//! - XXX +//! +//! # Types +//! +//! Sequoia objects are opaque objects. They are created in +//! constructors, and must be freed when no longer needed. +//! +//! Pointers handed to Sequoia must not be `NULL`, unless explicitly +//! stated. See [references]. +//! +//! [references]: #references +//! +//! Enumeration-like values must be in the valid range. +//! +//! Strings must be UTF-8 encoded and zero-terminated. Malformed +//! characters will be substituted, and the result is likely not what +//! you expect. +//! +//! # Ownership +//! +//! When ownership of a `T` is transferred across the FFI boundary, a +//! `*mut T` is used. +//! +//! To transfer ownership from Rust to C, we box the Rust object, and +//! use [`Box::into_raw(..)`]. From this moment on, ownership must be +//! managed by the C application. +//! +//! [`Box::into_raw(..)`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.into_raw +//! +//! To transfer ownership from C to Rust, we re-create the box using +//! [`Box::from_raw(..)`]. +//! +//! [`Box::from_raw(..)`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.from_raw +//! +//! In this crate we use a series of macros to transfer ownership from +//! Rust to C. `fry_box` matches on `Result<T>`, handling errors by +//! terminating the current function, returning the error using the +//! context. `maybe_box_raw` matches on `Option<T>`, turning `None` +//! into `NULL`. Finally, `box_raw` is merely a shortcut for +//! `Box::into_raw(Box::new(..))`. +//! +//! # References +//! +//! When references are transferred across the FFI boundary, we use +//! `*const T`, or `*mut T`. If the parameter is optional, a +//! `Option<&T>` or `Option<&mut T>` is used. +//! +//! Application code must adhere to Rust's reference rules: +//! +//! - Either one mutable reference or any number of immutable ones. +//! - All references are non-`NULL`. +//! - All references are valid. +//! +//! In this crate we enforce the second rule by asserting that all +//! pointers handed in are non-`NULL`. If a parameter of an FFI +//! function uses `Option<&T>` or `Option<&mut T>`, it may be called +//! with `NULL`. A notable example are the destructors (`sq_*_free`). +//! +//! # Lifetimes +//! +//! If you derive a complex object from another complex object, you +//! must assume that the original object is borrowed by the resulting +//! object unless explicitly stated otherwise. For example, objects +//! created using a context must not outlive that context. Similarly, +//! iterators must not outlive the object they are created from. +//! +//! Failing to adhere to lifetime restrictions results in undefined +//! behavior. +//! +//! # Error handling +//! +//! Sequoia will panic if you provide bad arguments, e.g. hand a +//! `NULL` pointer to a function that does not explicitly allow this. +//! +//! Failing functions return `NULL`. Functions that require a +//! `Context` return complex errors. Complex errors are stored in the +//! `Context`, and can be retrieved using `sq_last_strerror`. +//! +//! # Example +//! +//! ```c +//! #include <sequoia/openpgp.h> +//! #include <error.h> +//! +//! sq_error_t err; +//! sq_tpk_t tpk; +//! +//! tpk = sq_tpk_from_file (&err, "../openpgp/tests/data/keys/testy.pgp"); +//! if (tpk == NULL) +//! error (1, 0, "sq_tpk_from_bytes: %s", sq_error_string (err)); +//! +//! sq_tpk_free (tpk); +//! ``` + +#![warn(missing_docs)] + +extern crate failure; +#[macro_use] +extern crate lazy_static; +extern crate libc; + +extern crate sequoia_ffi_macros; +use sequoia_ffi_macros::ffi_catch_abort; + +include!("common.rs"); |