I am trying to read the contents from the ISO image using Rust. I have installed libiso9660-dev
and libcdio-dev
on my Linux machine to get access to the header files. Libiso9660 is a library to work with ISO9660
filesystems (development files). I used bindgen to generate bindings to the library. Until this point, everything was pretty straightforward.
Here is the part of the bindings relevant to my code:
extern "C" {
pub fn iso9660_open(psz_path: *const ::std::os::raw::c_char) -> *mut iso9660_t;
}
extern "C" {
pub fn iso9660_ifs_get_application_id(
p_iso: *mut iso9660_t,
p_psz_app_id: *mut *mut cdio_utf8_t,
) -> ::std::os::raw::c_uchar;
}
The next step is to use generated bindings. Here is the relevant code:
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
use std::os::raw::{c_char};
use std::ffi::{CString};
use std::ptr;
pub fn open_image(path: &str) {
let c_str = CString::new(path).unwrap();
let psz_path = c_str.as_ptr() as *const c_char;
let image = unsafe { iso9660_open(psz_path) };
get_image_info(image);
}
fn get_image_info(image: *mut iso9660_t) {
println!("Getting image info...");
let ptr_null = ptr::null_mut();
let app_info = unsafe { iso9660_ifs_get_application_id(image, ptr_null) };
// here is the "segmentation fault (core dumped)"
}
Here is the example that I want to replicate in Rust (line 89 is where I am at this point).
open_image
seems to be working, but I get the segmentation fault when I call iso9660_ifs_get_application_id
. I assume that I am not calling the method as I should because of the types, but other than that, I have nothing. Any hint or help would be highly appreciated. Thank you!
Notice the type of the p_psz_app_id
parameter: *mut *mut cdio_utf8_t
. It is a double pointer. Here is what the C example code is doing:
char *psz_str = NULL;
if (iso9660_ifs_get_application_id(p_iso, &psz_str)) {
printf(title ": %s\n", psz_str);
}
free(psz_str);
psz_str = NULL;
It's passing &psz_str
to the iso9660_ifs_get_application_id()
function. Here, &psz_str
is a valid pointer pointing to the null pointer psz_str
; it is not itself a null pointer. The Rust code is passing in a null pointer for this parameter, which is the issue.