use std::env;
use virt::{
connect::Connect,
domain::Domain,
error::clear_error_callback,
stream::Stream,
sys::{
virEventRegisterDefaultImpl, virEventRunDefaultImpl, virStreamEventType,
VIR_DOMAIN_CONSOLE_FORCE, VIR_STREAM_EVENT_READABLE, VIR_STREAM_NONBLOCK,
},
};
fn read_callback(stream: &Stream, event_type: virStreamEventType) {
if event_type == VIR_STREAM_EVENT_READABLE {
let mut buf = vec![0; 1024];
match stream.recv(buf.as_mut_slice()) {
Ok(t) => {
if let Ok(received_data) = std::str::from_utf8(&buf[..t]) {
print!("{received_data}");
} else {
eprint!("Invalid UTF-8 sequence received.");
}
}
Err(e) => {
println!("{e}");
}
}
}
}
fn event_register_default_impl() {
unsafe { virEventRegisterDefaultImpl() };
}
fn event_run_default_impl() {
unsafe { virEventRunDefaultImpl() };
}
fn main() {
clear_error_callback();
event_register_default_impl();
let uri = env::args().nth(1);
let name = env::args().nth(2).unwrap();
let dev_name = env::args().nth(3);
let conn = Connect::open(uri.as_deref()).unwrap();
let dom = Domain::lookup_by_name(&conn, &name).unwrap();
let mut st = Stream::new(&conn, VIR_STREAM_NONBLOCK).unwrap();
dom.open_console(dev_name.as_deref(), &st, VIR_DOMAIN_CONSOLE_FORCE)
.unwrap();
st.event_add_callback(VIR_STREAM_EVENT_READABLE, move |st, event_type| {
read_callback(st, event_type)
})
.unwrap();
loop {
event_run_default_impl();
}
}