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 /ffi/src/core.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 'ffi/src/core.rs')
-rw-r--r-- | ffi/src/core.rs | 175 |
1 files changed, 1 insertions, 174 deletions
diff --git a/ffi/src/core.rs b/ffi/src/core.rs index 915dcffc..f644dc4b 100644 --- a/ffi/src/core.rs +++ b/ffi/src/core.rs @@ -39,15 +39,8 @@ //! ``` use failure; -use std::fs::File; -use std::io::{self, Read, Write, Cursor}; -use std::path::Path; use std::ptr; -use std::slice; -use libc::{uint8_t, c_void, c_char, c_int, size_t, ssize_t, realloc}; - -#[cfg(unix)] -use std::os::unix::io::FromRawFd; +use libc::{uint8_t, c_char, c_int}; use sequoia_core as core; use sequoia_core::Config; @@ -225,169 +218,3 @@ pub extern "system" fn sq_config_ephemeral(cfg: *mut Config) { let cfg = ffi_param_ref_mut!(cfg); cfg.set_ephemeral(); } - -/* Reader and writer. */ - -/// Opens a file returning a reader. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_from_file(errp: Option<&mut *mut failure::Error>, - filename: *const c_char) - -> *mut Box<Read> { - ffi_make_fry_from_errp!(errp); - let filename = ffi_param_cstr!(filename).to_string_lossy().into_owned(); - ffi_try_box!(File::open(Path::new(&filename)) - .map(|r| Box::new(r)) - .map_err(|e| e.into())) -} - -/// Opens a file descriptor returning a reader. -#[cfg(unix)] -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_from_fd(fd: c_int) - -> *mut Box<Read> { - box_raw!(Box::new(unsafe { File::from_raw_fd(fd) })) -} - -/// Creates a reader from a buffer. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_from_bytes(buf: *const uint8_t, - len: size_t) - -> *mut Box<Read> { - assert!(!buf.is_null()); - let buf = unsafe { - slice::from_raw_parts(buf, len as usize) - }; - box_raw!(Box::new(Cursor::new(buf))) -} - -/// Frees a reader. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_free(reader: Option<&mut Box<Read>>) { - ffi_free!(reader) -} - -/// Reads up to `len` bytes into `buf`. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_read(errp: Option<&mut *mut failure::Error>, - reader: *mut Box<Read>, - buf: *mut uint8_t, len: size_t) - -> ssize_t { - ffi_make_fry_from_errp!(errp); - let reader = ffi_param_ref_mut!(reader); - assert!(!buf.is_null()); - let buf = unsafe { - slice::from_raw_parts_mut(buf, len as usize) - }; - ffi_try_or!(reader.read(buf).map_err(|e| e.into()), -1) as ssize_t -} - - -/// Opens a file returning a writer. -/// -/// The file will be created if it does not exist, or be truncated -/// otherwise. If you need more control, use `sq_writer_from_fd`. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_from_file(errp: Option<&mut *mut failure::Error>, - filename: *const c_char) - -> *mut Box<Write> { - ffi_make_fry_from_errp!(errp); - let filename = ffi_param_cstr!(filename).to_string_lossy().into_owned(); - ffi_try_box!(File::create(Path::new(&filename)) - .map(|r| Box::new(r)) - .map_err(|e| e.into())) -} - -/// Opens a file descriptor returning a writer. -#[cfg(unix)] -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_from_fd(fd: c_int) - -> *mut Box<Write> { - box_raw!(Box::new(unsafe { File::from_raw_fd(fd) })) -} - -/// Creates a writer from a buffer. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_from_bytes(buf: *mut uint8_t, - len: size_t) - -> *mut Box<Write> { - assert!(!buf.is_null()); - let buf = unsafe { - slice::from_raw_parts_mut(buf, len as usize) - }; - box_raw!(Box::new(Cursor::new(buf))) -} - -/// Creates an allocating writer. -/// -/// This writer allocates memory using `malloc`, and stores the -/// pointer to the memory and the number of bytes written to the given -/// locations `buf`, and `len`. Both must either be set to zero, or -/// reference a chunk of memory allocated using libc's heap allocator. -/// The caller is responsible to `free` it once the writer has been -/// destroyed. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_alloc(buf: *mut *mut c_void, - len: *mut size_t) - -> *mut Box<Write> { - let buf = ffi_param_ref_mut!(buf); - let len = ffi_param_ref_mut!(len); - - box_raw!(Box::new(WriterAlloc { - buf: buf, - len: len, - })) -} - -struct WriterAlloc { - buf: &'static mut *mut c_void, - len: &'static mut size_t, -} - -impl Write for WriterAlloc { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - let old_len = *self.len; - let new_len = old_len + buf.len(); - - let new = unsafe { - realloc(*self.buf, new_len) - }; - if new.is_null() { - return Err(io::Error::new(io::ErrorKind::Other, "out of memory")); - } - - *self.buf = new; - *self.len = new_len; - - let sl = unsafe { - slice::from_raw_parts_mut(new as *mut u8, new_len) - }; - &mut sl[old_len..].copy_from_slice(buf); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - // Do nothing. - Ok(()) - } -} - -/// Frees a writer. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_free(writer: Option<&mut Box<Write>>) { - ffi_free!(writer) -} - -/// Writes up to `len` bytes of `buf` into `writer`. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_write(errp: Option<&mut *mut failure::Error>, - writer: *mut Box<Write>, - buf: *const uint8_t, len: size_t) - -> ssize_t { - ffi_make_fry_from_errp!(errp); - let writer = ffi_param_ref_mut!(writer); - assert!(!buf.is_null()); - let buf = unsafe { - slice::from_raw_parts(buf, len as usize) - }; - ffi_try_or!(writer.write(buf).map_err(|e| e.into()), -1) as ssize_t -} |