1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use crate::parse;
use crate::parse::Interface;
use crate::GetRequestAns;
use std::fs;
use std::io::{BufRead, BufReader};
use std::os::unix::net::{UnixListener, UnixStream};
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::thread;
type Handle =
fn(&mut Interface, String) -> parse::Result<Option<GetRequestAns<'_>>>;
pub struct IPCServer {
listener: UnixListener,
interface: Arc<Mutex<Interface>>,
handler: Arc<Box<Handle>>,
}
impl IPCServer {
const LOCATION: &'static str = "/tmp/msb-final-ipc-socket";
pub fn new(
handler: Box<Handle>,
interface: Interface,
) -> std::io::Result<Self> {
let socket = Path::new(Self::LOCATION);
if socket.exists() {
fs::remove_file(&socket).unwrap();
}
Ok(Self {
listener: UnixListener::bind(&socket)?,
interface: Arc::new(Mutex::new(interface)),
handler: Arc::new(handler),
})
}
pub fn main_loop(&self) {
for stream in self.listener.incoming() {
let handle = self.handler.clone();
let interface = self.interface.clone();
thread::spawn(move || {
Self::handle(stream.unwrap(), handle, interface)
});
}
}
fn handle(
conn: UnixStream,
handler: Arc<Box<Handle>>,
interface: Arc<Mutex<Interface>>,
) {
let stream = BufReader::new(conn);
for line in stream.lines() {
match line {
Ok(s) => {
match (**handler)(&mut interface.clone().lock().unwrap(), s)
{
Err(e) => println!("{:?}", e),
Ok(o) => println!("{:?}", o),
};
}
Err(_) => {}
};
}
}
}
impl Drop for IPCServer {
fn drop(&mut self) {
fs::remove_file(Self::LOCATION).unwrap();
}
}