use super::{CommsEnvError, CommsEnvErrorRepr};
pub struct CommsInRaw {
fd: libc::c_int,
}
pub struct CommsOutRaw {
fd: libc::c_int,
}
impl CommsInRaw {
pub fn from_env() -> Result<CommsInRaw, CommsEnvError> {
Ok(CommsInRaw {
fd: env_var_fd("FLEETSPEAK_COMMS_CHANNEL_INFD")?,
})
}
}
impl CommsOutRaw {
pub fn from_env() -> Result<CommsOutRaw, CommsEnvError> {
Ok(CommsOutRaw {
fd: env_var_fd("FLEETSPEAK_COMMS_CHANNEL_OUTFD")?,
})
}
}
impl std::io::Read for CommsInRaw {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let count = unsafe {
libc::read(self.fd, buf.as_mut_ptr().cast(), buf.len())
};
if count < 0 {
return Err(std::io::Error::last_os_error());
}
Ok(count as usize)
}
}
impl std::io::Write for CommsOutRaw {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let count = unsafe {
libc::write(self.fd, buf.as_ptr().cast(), buf.len())
};
if count < 0 {
return Err(std::io::Error::last_os_error());
}
Ok(count as usize)
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
fn env_var_fd<K>(key: K) -> Result<libc::c_int, CommsEnvError>
where
K: AsRef<std::ffi::OsStr>,
{
match std::env::var(key) {
Ok(fd) => match fd.parse::<libc::c_int>() {
Ok(fd) => Ok(fd),
Err(_) => Err(CommsEnvError {
repr: CommsEnvErrorRepr::NotParsable(fd.into()),
}),
}
Err(std::env::VarError::NotPresent) => Err(CommsEnvError {
repr: CommsEnvErrorRepr::NotSpecified,
}),
Err(std::env::VarError::NotUnicode(value)) => Err(CommsEnvError {
repr: CommsEnvErrorRepr::NotParsable(value),
}),
}
}