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
96
97
98
99
use std::error::Error;
use std::io::{Error as IoError, ErrorKind, Read, Write};
use std::os::unix::net::UnixStream;
use std::time::{Duration, SystemTime};
use crate::unix_proto::{ClientRequest, ClientResponse};
pub fn call_daemon_blocking(
path: &str,
req: &ClientRequest,
timeout: u64,
) -> Result<ClientResponse, Box<dyn Error>> {
let timeout = Duration::from_secs(timeout);
let mut stream = UnixStream::connect(path)
.and_then(|socket| socket.set_read_timeout(Some(timeout)).map(|_| socket))
.and_then(|socket| socket.set_write_timeout(Some(timeout)).map(|_| socket))
.map_err(|e| {
error!("stream setup error -> {:?}", e);
e
})
.map_err(Box::new)?;
let data = serde_json::to_vec(&req).map_err(|e| {
error!("socket encoding error -> {:?}", e);
Box::new(IoError::new(ErrorKind::Other, "JSON encode error"))
})?;
stream
.write_all(data.as_slice())
.and_then(|_| stream.flush())
.map_err(|e| {
error!("stream write error -> {:?}", e);
e
})
.map_err(Box::new)?;
let start = SystemTime::now();
let mut read_started = false;
let mut data = Vec::with_capacity(1024);
let mut counter = 0;
loop {
let mut buffer = [0; 1024];
let durr = SystemTime::now().duration_since(start).map_err(Box::new)?;
if durr > timeout {
error!("Socket timeout");
break;
}
match stream.read(&mut buffer) {
Ok(0) => {
if read_started {
debug!("read_started true, we have completed");
break;
} else {
debug!("Waiting ...");
continue;
}
}
Ok(count) => {
data.extend_from_slice(&buffer);
counter += count;
if count == 1024 {
debug!("Filled 1024 bytes, looping ...");
read_started = true;
continue;
} else {
debug!("Filled {} bytes, complete", count);
break;
}
}
Err(e) => {
error!("Steam read failure -> {:?}", e);
return Err(Box::new(e));
}
}
}
data.truncate(counter);
let cr = serde_json::from_slice::<ClientResponse>(data.as_slice()).map_err(|e| {
error!("socket encoding error -> {:?}", e);
Box::new(IoError::new(ErrorKind::Other, "JSON decode error"))
})?;
Ok(cr)
}