#![cfg(any(target_os = "linux", target_os = "l4re", target_os = "android"))]
use {
core::time::Duration,
std::{
os::{
fd::AsRawFd,
linux::net::SocketAddrExt,
unix::net::{SocketAddr, UnixListener},
},
sync::mpsc::{self, RecvTimeoutError},
thread,
},
crate::{Result, UdsxUnixStream},
};
type Message = ();
type Sender = mpsc::Sender<Message>;
pub (crate) const STREAM_ID: &[u8] = &[
0x1e, 0x64, 0x83, 0x1b, 0xfb, 0x9a, 0x2d, 0x3d, 0x58, 0x80, 0x8c, 0xc2, 0xfd, 0xd3, 0x92, 0x23, 0x48, 0x5f, 0xe1, 0x8d, 0xdb, 0x80, 0x62,
0x16, 0xe7, 0xd7, 0xa7, 0x3b, 0x9a, 0x27, 0x0c, 0xdd, 0xfe, 0x4b, 0x51, 0x92, 0xd0, 0xb2, 0x0c, 0xb5, 0xb8, 0x58, 0x95, 0x24, 0x3b, 0xec,
0x75, 0xb5, 0x08, 0x1e, 0x27, 0x85, 0x0b, 0xd7, 0xcb, 0xb4, 0x0c, 0xbd, 0x30, 0x6d, 0x62, 0x5e, 0x0c, 0xcc,
];
#[derive(Debug)]
pub struct Namaste {
_sender: Sender,
}
impl Namaste {
pub (crate) fn make<B>(id: B) -> Result<Self> where B: AsRef<[u8]> {
Self::make_from_unix_listener(UnixListener::bind_addr(&SocketAddr::from_abstract_name(&id)?)?)
}
pub (crate) fn make_from_unix_listener(unix_listener: UnixListener) -> Result<Self> {
Ok(Self {
_sender: spawn_thread(unix_listener)?,
})
}
}
fn spawn_thread(unix_listener: UnixListener) -> Result<Sender> {
unix_listener.set_nonblocking(true)?;
let (sender, receiver) = mpsc::channel();
thread::spawn(move || for stream in unix_listener.incoming() {
match stream {
Ok(stream) => if stream.send_streams(STREAM_ID, [unix_listener.as_raw_fd()]).is_err() {
},
Err(_) => match receiver.recv_timeout(Duration::from_millis(10)) {
Ok(()) => return,
Err(RecvTimeoutError::Timeout) => continue,
Err(RecvTimeoutError::Disconnected) => return,
},
};
});
Ok(sender)
}