Skip to content

Commit

Permalink
rust: Move FFI bits into ffi submodule for each file
Browse files Browse the repository at this point in the history
The `lib.rs` file was starting to accumulate, and I want to do this
before adding more.  I just made this up, but an `ffi` submodule
in each file seems to work well.  It isolates the FFI consumption
there still (so e.g. if we want pure Rust unit tests, we don't
need to deal with FFI).

Closes: #1646
Approved by: jlebon
  • Loading branch information
cgwalters authored and rh-atomic-bot committed Oct 30, 2018
1 parent 99776be commit 87441d9
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 133 deletions.
14 changes: 14 additions & 0 deletions rust/src/journal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,17 @@ pub fn journal_print_staging_failure() -> io::Result<()> {

return print_staging_failure_msg(None);
}

mod ffi {
use super::*;
use ffiutil::*;
use glib_sys;
use libc;
#[no_mangle]
pub extern "C" fn ror_journal_print_staging_failure(
gerror: *mut *mut glib_sys::GError,
) -> libc::c_int {
int_glib_error(journal_print_staging_failure(), gerror)
}
}
pub use self::ffi::*;
137 changes: 4 additions & 133 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,140 +31,11 @@ extern crate serde;
extern crate serde_json;
extern crate serde_yaml;

use std::ffi::OsStr;
use std::io::Seek;
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use std::{fs, io, ptr};

mod ffiutil;
use ffiutil::*;

mod treefile;
use treefile::*;
pub use treefile::*;
mod journal;
use journal::*;
pub use journal::*;
mod utils;

// Some of our file descriptors may be read multiple times.
// We try to consistently seek to the start to make that
// convenient from the C side. Note that this function
// will abort if seek() fails (it really shouldn't).
fn raw_seeked_fd(fd: &mut fs::File) -> RawFd {
fd.seek(io::SeekFrom::Start(0)).expect("seek");
fd.as_raw_fd()
}

#[no_mangle]
pub extern "C" fn ror_treefile_new(
filename: *const libc::c_char,
arch: *const libc::c_char,
workdir_dfd: libc::c_int,
gerror: *mut *mut glib_sys::GError,
) -> *mut Treefile {
// Convert arguments
let filename = OsStr::from_bytes(bytes_from_nonnull(filename));
let arch = str_from_nullable(arch);
let workdir = match dir_from_dfd(workdir_dfd) {
Ok(p) => p,
Err(e) => {
error_to_glib(&e, gerror);
return ptr::null_mut();
}
};
// Run code, map error if any, otherwise extract raw pointer, passing
// ownership back to C.
ptr_glib_error(
Treefile::new_boxed(filename.as_ref(), arch, workdir),
gerror,
)
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_dfd(tf: *mut Treefile) -> libc::c_int {
ref_from_raw_ptr(tf).primary_dfd.as_raw_fd()
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_postprocess_script_fd(tf: *mut Treefile) -> libc::c_int {
ref_from_raw_ptr(tf)
.externals
.postprocess_script
.as_mut()
.map_or(-1, raw_seeked_fd)
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_add_file_fd(
tf: *mut Treefile,
filename: *const libc::c_char,
) -> libc::c_int {
let tf = ref_from_raw_ptr(tf);
let filename = OsStr::from_bytes(bytes_from_nonnull(filename));
let filename = filename.to_string_lossy().into_owned();
raw_seeked_fd(tf.externals.add_files.get_mut(&filename).expect("add-file"))
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_passwd_fd(tf: *mut Treefile) -> libc::c_int {
ref_from_raw_ptr(tf)
.externals
.passwd
.as_mut()
.map_or(-1, raw_seeked_fd)
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_group_fd(tf: *mut Treefile) -> libc::c_int {
ref_from_raw_ptr(tf)
.externals
.group
.as_mut()
.map_or(-1, raw_seeked_fd)
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_json_string(tf: *mut Treefile) -> *const libc::c_char {
ref_from_raw_ptr(tf).serialized.as_ptr()
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_rojig_spec_path(tf: *mut Treefile) -> *const libc::c_char {
let tf = ref_from_raw_ptr(tf);
if let &Some(ref rojig) = &tf.rojig_spec {
rojig.as_ptr()
} else {
ptr::null_mut()
}
}

#[no_mangle]
pub extern "C" fn ror_treefile_free(tf: *mut Treefile) {
if tf.is_null() {
return;
}
unsafe {
Box::from_raw(tf);
}
}

#[no_mangle]
pub extern "C" fn ror_download_to_fd(
url: *const libc::c_char,
gerror: *mut *mut glib_sys::GError,
) -> libc::c_int {
let url = str_from_nullable(url).unwrap();
match utils::download_url_to_tmpfile(url) {
Ok(f) => f.into_raw_fd(),
Err(e) => {
error_to_glib(&e, gerror);
-1
}
}
}

#[no_mangle]
pub extern "C" fn ror_journal_print_staging_failure(
gerror: *mut *mut glib_sys::GError,
) -> libc::c_int {
int_glib_error(journal_print_staging_failure(), gerror)
}
pub use utils::*;
117 changes: 117 additions & 0 deletions rust/src/treefile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,3 +784,120 @@ packages:
assert!(rojig.name == "exampleos");
}
}

mod ffi {
use super::*;
use ffiutil::*;
use glib_sys;
use libc;

use std::ffi::OsStr;
use std::io::Seek;
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsRawFd, RawFd};
use std::{fs, io, ptr};

// Some of our file descriptors may be read multiple times.
// We try to consistently seek to the start to make that
// convenient from the C side. Note that this function
// will abort if seek() fails (it really shouldn't).
fn raw_seeked_fd(fd: &mut fs::File) -> RawFd {
fd.seek(io::SeekFrom::Start(0)).expect("seek");
fd.as_raw_fd()
}

#[no_mangle]
pub extern "C" fn ror_treefile_new(
filename: *const libc::c_char,
arch: *const libc::c_char,
workdir_dfd: libc::c_int,
gerror: *mut *mut glib_sys::GError,
) -> *mut Treefile {
// Convert arguments
let filename = OsStr::from_bytes(bytes_from_nonnull(filename));
let arch = str_from_nullable(arch);
let workdir = match dir_from_dfd(workdir_dfd) {
Ok(p) => p,
Err(e) => {
error_to_glib(&e, gerror);
return ptr::null_mut();
}
};
// Run code, map error if any, otherwise extract raw pointer, passing
// ownership back to C.
ptr_glib_error(
Treefile::new_boxed(filename.as_ref(), arch, workdir),
gerror,
)
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_dfd(tf: *mut Treefile) -> libc::c_int {
ref_from_raw_ptr(tf).primary_dfd.as_raw_fd()
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_postprocess_script_fd(tf: *mut Treefile) -> libc::c_int {
ref_from_raw_ptr(tf)
.externals
.postprocess_script
.as_mut()
.map_or(-1, raw_seeked_fd)
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_add_file_fd(
tf: *mut Treefile,
filename: *const libc::c_char,
) -> libc::c_int {
let tf = ref_from_raw_ptr(tf);
let filename = OsStr::from_bytes(bytes_from_nonnull(filename));
let filename = filename.to_string_lossy().into_owned();
raw_seeked_fd(tf.externals.add_files.get_mut(&filename).expect("add-file"))
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_passwd_fd(tf: *mut Treefile) -> libc::c_int {
ref_from_raw_ptr(tf)
.externals
.passwd
.as_mut()
.map_or(-1, raw_seeked_fd)
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_group_fd(tf: *mut Treefile) -> libc::c_int {
ref_from_raw_ptr(tf)
.externals
.group
.as_mut()
.map_or(-1, raw_seeked_fd)
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_json_string(tf: *mut Treefile) -> *const libc::c_char {
ref_from_raw_ptr(tf).serialized.as_ptr()
}

#[no_mangle]
pub extern "C" fn ror_treefile_get_rojig_spec_path(tf: *mut Treefile) -> *const libc::c_char {
let tf = ref_from_raw_ptr(tf);
if let &Some(ref rojig) = &tf.rojig_spec {
rojig.as_ptr()
} else {
ptr::null_mut()
}
}

#[no_mangle]
pub extern "C" fn ror_treefile_free(tf: *mut Treefile) {
if tf.is_null() {
return;
}
unsafe {
Box::from_raw(tf);
}
}

}
pub use self::ffi::*;
24 changes: 24 additions & 0 deletions rust/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,27 @@ pub fn download_url_to_tmpfile(url: &str) -> io::Result<fs::File> {
tmpf.seek(io::SeekFrom::Start(0))?;
Ok(tmpf)
}

mod ffi {
use super::*;
use glib_sys;
use libc;
use std::os::unix::io::IntoRawFd;

#[no_mangle]
pub extern "C" fn ror_download_to_fd(
url: *const libc::c_char,
gerror: *mut *mut glib_sys::GError,
) -> libc::c_int {
use ffiutil::*;
let url = str_from_nullable(url).unwrap();
match download_url_to_tmpfile(url) {
Ok(f) => f.into_raw_fd(),
Err(e) => {
error_to_glib(&e, gerror);
-1
}
}
}
}
pub use self::ffi::*;

0 comments on commit 87441d9

Please sign in to comment.