1
Fork 0
rust-ipc/src/main.rs

98 lines
2.2 KiB
Rust

use rand::{thread_rng, RngCore};
use std::env;
use std::fs::remove_file;
use std::io::{BufRead, BufReader, Write};
use std::os::unix::net::{UnixListener, UnixStream};
use std::path::{Path, PathBuf};
use std::process::Command;
use std::thread;
use std::time::{SystemTime, UNIX_EPOCH};
const ENV_VAR: &str = "IPC_SOCK_PATH";
struct SocketServer {
socket_path: PathBuf,
listener: UnixListener,
}
impl SocketServer {
fn new() -> Self {
let socket_path = create_socket();
SocketServer {
socket_path: socket_path.clone(),
listener: UnixListener::bind(&socket_path).unwrap(),
}
}
fn run(&self) {
println!("Listening on {}", self.socket_path.display());
for stream in self.listener.incoming() {
println!("New connection");
match stream {
Ok(stream) => {
thread::spawn(|| handle_client(stream));
}
Err(err) => {
println!("Connection failed: {:?}", err);
}
}
}
}
fn path(&self) -> &Path {
&self.socket_path
}
}
impl Drop for SocketServer {
fn drop(&mut self) {
remove_file(&self.socket_path).unwrap();
}
}
fn create_socket() -> PathBuf {
let mut temp_dir = env::temp_dir();
let now = SystemTime::now();
let seed = thread_rng().next_u32();
let secs = now.duration_since(UNIX_EPOCH).unwrap().as_secs();
temp_dir.push(&format!("rust-ipc-{secs}-{seed}.sock"));
temp_dir
}
fn handle_client(stream: UnixStream) {
let reader = BufReader::new(stream);
for line in reader.lines() {
dbg!(line.unwrap());
}
println!("Closed - killing thread");
}
fn client(path: String) {
let mut stream = UnixStream::connect(path).unwrap();
stream.write_all(b"Hello World").unwrap();
}
fn main() {
if let Ok(path) = env::var(ENV_VAR) {
client(path);
} else {
let server = SocketServer::new();
let _child = Command::new(env::current_exe().unwrap())
.env(ENV_VAR, server.path())
.spawn()
.unwrap();
server.run();
}
}