use mio::net::UnixListener; use mio::{Events, Interest, Poll, Token}; use mio_signals::{Signal, Signals}; use std::ops::{Deref, DerefMut}; use std::path::{Path, PathBuf}; use std::time::Duration; const SOCK_NAME: &str = "magpie.sock"; /// Wraps [mio::net::UnixListener] with automatic file deletion on drop. pub struct Listener { pub uds: UnixListener, pub path: PathBuf, } impl Drop for Listener { fn drop(&mut self) { match std::fs::remove_file(&self.path) { Ok(_) => {} Err(e) => eprintln!("Could not delete UnixListener {:?}", e), } } } impl Deref for Listener { type Target = UnixListener; fn deref(&self) -> &UnixListener { &self.uds } } impl DerefMut for Listener { fn deref_mut(&mut self) -> &mut UnixListener { &mut self.uds } } fn main() -> std::io::Result<()> { let sock_dir = std::env::var("XDG_RUNTIME_DIR").expect("XDG_RUNTIME_DIR not set"); let sock_dir = Path::new(&sock_dir); let sock_path = sock_dir.join(SOCK_NAME); eprintln!("Making socket at: {:?}", sock_path); let mut listener = Listener { uds: UnixListener::bind(&sock_path)?, path: sock_path.to_path_buf(), }; let mut signals = Signals::new(Signal::Interrupt | Signal::Quit)?; let mut poll = Poll::new()?; let mut events = Events::with_capacity(128); const LISTENER: Token = Token(0); poll.registry() .register(&mut listener.uds, LISTENER, Interest::READABLE)?; const SIGNALS: Token = Token(1); poll.registry() .register(&mut signals, SIGNALS, Interest::READABLE)?; let mut quit = false; while !quit { let wait = Duration::from_millis(100); poll.poll(&mut events, Some(wait))?; for event in events.iter() { match event.token() { LISTENER => loop { match listener.accept() { Ok((connection, address)) => { println!("Got a connection from: {:?}", address); } Err(ref err) if err.kind() == std::io::ErrorKind::WouldBlock => break, Err(err) => return Err(err), } }, SIGNALS => while let Some(received) = signals.receive()? { eprintln!("Received {:?} signal; exiting...", received); quit = true; } _ => panic!("Unrecognized event token: {:?}", event), } } } Ok(()) }