90 lines
2.5 KiB
Rust
90 lines
2.5 KiB
Rust
|
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(())
|
||
|
}
|