105 lines
3.1 KiB
Rust
105 lines
3.1 KiB
Rust
/*
|
|
* This file is part of espanso.
|
|
*
|
|
* Copyright (C) 2019 Federico Terzi
|
|
*
|
|
* espanso is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* espanso is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
use super::IPCCommand;
|
|
use log::{info, warn};
|
|
use std::os::unix::net::{UnixListener, UnixStream};
|
|
use std::sync::mpsc::Sender;
|
|
|
|
use super::Service;
|
|
use crate::context;
|
|
use crate::event::*;
|
|
use crate::protocol::{process_event, send_command};
|
|
|
|
const DAEMON_UNIX_SOCKET_NAME: &str = "espanso.sock";
|
|
const WORKER_UNIX_SOCKET_NAME: &str = "worker.sock";
|
|
|
|
pub struct UnixIPCServer {
|
|
service: Service,
|
|
event_channel: Sender<Event>,
|
|
}
|
|
|
|
impl UnixIPCServer {
|
|
pub fn new(service: Service, event_channel: Sender<Event>) -> UnixIPCServer {
|
|
UnixIPCServer {
|
|
service,
|
|
event_channel,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get_unix_name(service: &Service) -> String {
|
|
match service {
|
|
Service::Daemon => DAEMON_UNIX_SOCKET_NAME.to_owned(),
|
|
Service::Worker => WORKER_UNIX_SOCKET_NAME.to_owned(),
|
|
}
|
|
}
|
|
|
|
impl super::IPCServer for UnixIPCServer {
|
|
fn start(&self) {
|
|
let event_channel = self.event_channel.clone();
|
|
let socket_name = get_unix_name(&self.service);
|
|
std::thread::Builder::new()
|
|
.name("ipc_server".to_string())
|
|
.spawn(move || {
|
|
let espanso_dir = context::get_data_dir();
|
|
let unix_socket = espanso_dir.join(socket_name);
|
|
|
|
std::fs::remove_file(unix_socket.clone()).unwrap_or_else(|e| {
|
|
warn!("Unable to delete Unix socket: {}", e);
|
|
});
|
|
let listener =
|
|
UnixListener::bind(unix_socket.clone()).expect("Can't bind to Unix Socket");
|
|
|
|
info!(
|
|
"Binded to IPC unix socket: {}",
|
|
unix_socket.as_path().display()
|
|
);
|
|
|
|
for stream in listener.incoming() {
|
|
process_event(&event_channel, stream);
|
|
}
|
|
})
|
|
.expect("Unable to spawn IPC server thread");
|
|
}
|
|
}
|
|
|
|
pub struct UnixIPCClient {
|
|
service: Service,
|
|
}
|
|
|
|
impl UnixIPCClient {
|
|
pub fn new(service: Service) -> UnixIPCClient {
|
|
UnixIPCClient { service }
|
|
}
|
|
}
|
|
|
|
impl super::IPCClient for UnixIPCClient {
|
|
fn send_command(&self, command: IPCCommand) -> Result<(), String> {
|
|
let espanso_dir = context::get_data_dir();
|
|
let socket_name = get_unix_name(&self.service);
|
|
let unix_socket = espanso_dir.join(socket_name);
|
|
|
|
// Open the stream
|
|
let stream = UnixStream::connect(unix_socket);
|
|
|
|
send_command(command, stream)
|
|
}
|
|
}
|