diff --git a/apps/magpie/src/service/ipc.rs b/apps/magpie/src/service/ipc.rs index c4271bf..ad9dce2 100644 --- a/apps/magpie/src/service/ipc.rs +++ b/apps/magpie/src/service/ipc.rs @@ -66,6 +66,35 @@ impl DerefMut for Listener { } } +impl Listener { + fn new() -> 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); + + use std::io::{Error, ErrorKind}; + match UnixStream::connect(&sock_path) { + Ok(_) => { + eprintln!("Socket is already in use. Another instance of Magpie may be running."); + let kind = ErrorKind::AddrInUse; + let error = Error::new(kind, "Socket is already in use."); + return Err(error); + } + Err(ref err) if err.kind() == ErrorKind::ConnectionRefused => { + eprintln!("Found leftover socket; removing."); + std::fs::remove_file(&sock_path)?; + } + Err(ref err) if err.kind() == ErrorKind::NotFound => {} + Err(err) => return Err(err), + } + + eprintln!("Making socket at: {:?}", sock_path); + let uds = UnixListener::bind(&sock_path)?; + let path = sock_path.to_path_buf(); + Ok(Self { uds, path }) + } +} + pub struct IpcData { poll: Poll, window_to_client_panel: HashMap, @@ -162,15 +191,7 @@ pub struct Ipc { impl Ipc { pub fn new(window_sender: WindowMessageSender) -> std::io::Result<(Self, IpcMessageSender)> { - 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 listener = Listener::new()?; let mut signals = Signals::new(Signal::Interrupt | Signal::Quit)?;