aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/ipc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/ipc.rs')
-rw-r--r--alacritty/src/ipc.rs69
1 files changed, 43 insertions, 26 deletions
diff --git a/alacritty/src/ipc.rs b/alacritty/src/ipc.rs
index 02aaf85f..6f02e757 100644
--- a/alacritty/src/ipc.rs
+++ b/alacritty/src/ipc.rs
@@ -1,8 +1,8 @@
//! Alacritty socket IPC.
use std::ffi::OsStr;
-use std::io::{Error as IoError, ErrorKind, Result as IoResult};
-use std::os::unix::net::UnixDatagram;
+use std::io::{BufRead, BufReader, Error as IoError, ErrorKind, Result as IoResult, Write};
+use std::os::unix::net::{UnixListener, UnixStream};
use std::path::PathBuf;
use std::{env, fs, process};
@@ -11,12 +11,9 @@ use log::warn;
use alacritty_terminal::thread;
-use crate::cli::Options;
+use crate::cli::{Options, SocketMessage};
use crate::event::{Event, EventType};
-/// IPC socket message for creating a new window.
-pub const SOCKET_MESSAGE_CREATE_WINDOW: [u8; 1] = [1];
-
/// Environment variable name for the IPC socket path.
const ALACRITTY_SOCKET_ENV: &str = "ALACRITTY_SOCKET";
@@ -30,8 +27,8 @@ pub fn spawn_ipc_socket(options: &Options, event_proxy: EventLoopProxy<Event>) -
});
env::set_var(ALACRITTY_SOCKET_ENV, socket_path.as_os_str());
- let socket = match UnixDatagram::bind(&socket_path) {
- Ok(socket) => socket,
+ let listener = match UnixListener::bind(&socket_path) {
+ Ok(listener) => listener,
Err(err) => {
warn!("Unable to create socket: {:?}", err);
return None;
@@ -40,13 +37,31 @@ pub fn spawn_ipc_socket(options: &Options, event_proxy: EventLoopProxy<Event>) -
// Spawn a thread to listen on the IPC socket.
thread::spawn_named("socket listener", move || {
- // Accept up to 2 bytes to ensure only one byte is received.
- // This ensures forward-compatibility.
- let mut buf = [0; 2];
-
- while let Ok(received) = socket.recv(&mut buf) {
- if buf[..received] == SOCKET_MESSAGE_CREATE_WINDOW {
- let _ = event_proxy.send_event(Event::new(EventType::CreateWindow, None));
+ let mut data = String::new();
+ for stream in listener.incoming().filter_map(Result::ok) {
+ data.clear();
+ let mut stream = BufReader::new(stream);
+
+ match stream.read_line(&mut data) {
+ Ok(0) | Err(_) => continue,
+ Ok(_) => (),
+ };
+
+ // Read pending events on socket.
+ let message: SocketMessage = match serde_json::from_str(&data) {
+ Ok(message) => message,
+ Err(err) => {
+ warn!("Failed to convert data from socket: {}", err);
+ continue;
+ },
+ };
+
+ // Handle IPC events.
+ match message {
+ SocketMessage::CreateWindow(terminal_options) => {
+ let event = Event::new(EventType::CreateWindow(Some(terminal_options)), None);
+ let _ = event_proxy.send_event(event);
+ },
}
}
});
@@ -55,9 +70,13 @@ pub fn spawn_ipc_socket(options: &Options, event_proxy: EventLoopProxy<Event>) -
}
/// Send a message to the active Alacritty socket.
-pub fn send_message(socket: Option<PathBuf>, message: &[u8]) -> IoResult<()> {
- let socket = find_socket(socket)?;
- socket.send(message)?;
+pub fn send_message(socket: Option<PathBuf>, message: SocketMessage) -> IoResult<()> {
+ let mut socket = find_socket(socket)?;
+
+ let message = serde_json::to_string(&message)?;
+ socket.write_all(message[..].as_bytes())?;
+ let _ = socket.flush();
+
Ok(())
}
@@ -78,22 +97,20 @@ fn socket_dir() -> PathBuf {
}
/// Find the IPC socket path.
-fn find_socket(socket_path: Option<PathBuf>) -> IoResult<UnixDatagram> {
- let socket = UnixDatagram::unbound()?;
-
+fn find_socket(socket_path: Option<PathBuf>) -> IoResult<UnixStream> {
// Handle --socket CLI override.
if let Some(socket_path) = socket_path {
// Ensure we inform the user about an invalid path.
- socket.connect(&socket_path).map_err(|err| {
+ return UnixStream::connect(&socket_path).map_err(|err| {
let message = format!("invalid socket path {:?}", socket_path);
IoError::new(err.kind(), message)
- })?;
+ });
}
// Handle environment variable.
if let Ok(path) = env::var(ALACRITTY_SOCKET_ENV) {
let socket_path = PathBuf::from(path);
- if socket.connect(&socket_path).is_ok() {
+ if let Ok(socket) = UnixStream::connect(&socket_path) {
return Ok(socket);
}
}
@@ -114,8 +131,8 @@ fn find_socket(socket_path: Option<PathBuf>) -> IoResult<UnixDatagram> {
}
// Attempt to connect to the socket.
- match socket.connect(&path) {
- Ok(_) => return Ok(socket),
+ match UnixStream::connect(&path) {
+ Ok(socket) => return Ok(socket),
// Delete orphan sockets.
Err(error) if error.kind() == ErrorKind::ConnectionRefused => {
let _ = fs::remove_file(&path);