use std::{env, net::Shutdown, os::unix::net::UnixStream, path::PathBuf, time}; use super::base::Connection; use error::Result; #[derive(Debug)] pub struct UnixConnection { socket: UnixStream, } impl Connection for UnixConnection { type Socket = UnixStream; fn connect() -> Result { let connection_name = Self::socket_path(0); let socket = UnixStream::connect(connection_name)?; socket.set_nonblocking(true)?; socket.set_write_timeout(Some(time::Duration::from_secs(30)))?; socket.set_read_timeout(Some(time::Duration::from_secs(30)))?; Ok(Self { socket }) } fn ipc_path() -> PathBuf { env::var_os("XDG_RUNTIME_DIR") .map(PathBuf::from) .map(|mut p| { // try flatpak dir p.push("app/com.discordapp.Discord"); if !p.exists() { p.pop(); p.pop(); } p }) .or_else(|| env::var_os("TMPDIR").map(PathBuf::from)) .or_else(|| match env::temp_dir().to_str() { None => None, Some(tmp) => Some(PathBuf::from(tmp)), }) .unwrap_or_else(|| PathBuf::from("/tmp")) } fn socket(&mut self) -> &mut Self::Socket { &mut self.socket } } impl Drop for UnixConnection { fn drop(&mut self) { self.socket .shutdown(Shutdown::Both) .expect("Failed to properly shut down socket"); } }