98 lines
2.2 KiB
Rust
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();
|
|
}
|
|
}
|