Wrap C functions

Signed-off-by: Ivan Bushchik <ivabus@ivabus.dev>
This commit is contained in:
Ivan Bushchik 2024-01-11 06:49:24 +03:00
parent 105372a965
commit f356c5528b
No known key found for this signature in database
GPG key ID: 2F16FBF3262E090C
2 changed files with 39 additions and 15 deletions

View file

@ -2,8 +2,8 @@ use rand::Rng;
use std::ffi::{c_char, CString}; use std::ffi::{c_char, CString};
extern "C" { extern "C" {
pub fn get_status(drive_path: *const c_char) -> std::ffi::c_int; pub fn c_get_status(drive_path: *const c_char) -> std::ffi::c_int;
pub fn eject(drive_path: *const c_char); pub fn c_eject(drive_path: *const c_char);
} }
fn sleep_rnd(start: u64, end: u64) { fn sleep_rnd(start: u64, end: u64) {
@ -12,6 +12,29 @@ fn sleep_rnd(start: u64, end: u64) {
std::thread::sleep(std::time::Duration::from_secs(sleeptime)); std::thread::sleep(std::time::Duration::from_secs(sleeptime));
} }
#[derive(PartialEq, Debug)]
enum Status {
Opened, // 0
Closed, // 1
Invalid, // 2
}
#[inline(always)]
fn get_status(drive_path: &CString) -> Status {
let status = unsafe { c_get_status(drive_path.as_ptr()) };
match status {
0 => Status::Opened,
1 => Status::Closed,
2 => Status::Invalid,
_ => panic!("Invalide status code from C module"),
}
}
#[inline(always)]
fn eject(drive_path: &CString) {
unsafe { c_eject(drive_path.as_ptr()) }
}
fn main() { fn main() {
let args = std::env::args().collect::<Vec<String>>(); let args = std::env::args().collect::<Vec<String>>();
if args.len() != 2 && args.len() != 4 { if args.len() != 2 && args.len() != 4 {
@ -26,18 +49,19 @@ fn main() {
} else { } else {
(5, 300) (5, 300)
}; };
let dr_name = CString::new(std::env::args().collect::<Vec<String>>()[1].as_bytes()).unwrap(); let dr_name = CString::new(args[1].as_bytes()).unwrap();
unsafe {
loop { loop {
if get_status(dr_name.as_ptr()) != 0x1 { if get_status(&dr_name) != Status::Closed {
while get_status(dr_name.as_ptr()) != 0x1_i32 { while get_status(&dr_name) != Status::Closed {
eprintln!("Status != closed, sleeping 250ms"); eprintln!(
"Status != closed ({:?}), sleeping 250ms",
get_status(&dr_name)
);
std::thread::sleep(std::time::Duration::from_millis(250)); std::thread::sleep(std::time::Duration::from_millis(250));
} }
sleep_rnd(start, end) sleep_rnd(start, end)
} }
eject(dr_name.as_ptr()); eject(&dr_name);
sleep_rnd(start, end); sleep_rnd(start, end);
} }
}
} }

View file

@ -6,7 +6,7 @@
// Status: 0 - opened, 1 - closed, 2 - failed // Status: 0 - opened, 1 - closed, 2 - failed
int get_status(char *drive_path) { int c_get_status(char *drive_path) {
int cdrom; int cdrom;
int status=1; int status=1;
@ -22,7 +22,7 @@ int get_status(char *drive_path) {
return status; return status;
} }
void eject(char *drive_path) { void c_eject(char *drive_path) {
// Ignore everything // Ignore everything
int cdrom; int cdrom;
cdrom = open(drive_path, O_RDONLY | O_NONBLOCK); cdrom = open(drive_path, O_RDONLY | O_NONBLOCK);