use super::stream::IpcWriter;
use fluxbench_ipc::{FrameReader, FrameWriter};
use std::io::{Read, Write};
#[cfg(unix)]
use std::os::unix::io::FromRawFd;
pub(super) type IpcReader = FrameReader<Box<dyn Read>>;
enum IpcTransport {
#[cfg(unix)]
Fds {
read_fd: i32,
write_fd: i32,
},
Stdio,
}
fn detect_transport() -> IpcTransport {
#[cfg(unix)]
if let Ok(val) = std::env::var("FLUX_IPC_FD") {
let parts: Vec<&str> = val.split(',').collect();
if parts.len() == 2 {
if let (Ok(r), Ok(w)) = (parts[0].parse::<i32>(), parts[1].parse::<i32>()) {
return IpcTransport::Fds {
read_fd: r,
write_fd: w,
};
}
}
eprintln!(
"fluxbench: warning: invalid FLUX_IPC_FD={val:?} (expected format: <read_fd>,<write_fd>), falling back to stdio"
);
}
IpcTransport::Stdio
}
pub(super) fn open() -> (IpcReader, IpcWriter) {
match detect_transport() {
#[cfg(unix)]
IpcTransport::Fds { read_fd, write_fd } => {
let read_file = unsafe { std::fs::File::from_raw_fd(read_fd) };
let write_file = unsafe { std::fs::File::from_raw_fd(write_fd) };
(
FrameReader::new(Box::new(read_file) as Box<dyn Read>),
FrameWriter::new(Box::new(write_file) as Box<dyn Write + Send>),
)
}
IpcTransport::Stdio => (
FrameReader::new(Box::new(std::io::stdin()) as Box<dyn Read>),
FrameWriter::new(Box::new(std::io::stdout()) as Box<dyn Write + Send>),
),
}
}