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
mod error;
pub use {
error::*,
};
pub fn query(
query: &str,
timeout_ms: isize,
) -> Result<String, XQError> {
const N: usize = 100;
let mut response = [0; N];
let n = query_buffer(query, &mut response, timeout_ms)?;
let s = std::str::from_utf8(&response[..n])?;
Ok(s.to_string())
}
#[cfg(not(unix))]
pub fn query_buffer(
_query: &str,
_buffer: &mut [u8],
_timeout_ms: isize,
) -> Result<usize, XQError> {
Err(XQError::Unsupported)
}
#[cfg(unix)]
pub fn query_buffer(
query: &str,
buffer: &mut [u8],
timeout_ms: isize,
) -> Result<usize, XQError> {
use nix::sys::epoll::*;
use std::io::{self, Read, Write};
let stdin = io::stdin();
let mut stdin = stdin.lock();
let stdout = io::stdout();
let mut stdout = stdout.lock();
write!(stdout, "{}", query)?;
stdout.flush()?;
let poll_fd = epoll_create1(EpollCreateFlags::empty())?;
let mut event = EpollEvent::new(EpollFlags::EPOLLIN, 0);
epoll_ctl(
poll_fd,
EpollOp::EpollCtlAdd,
nix::libc::STDIN_FILENO,
Some(& mut event),
)?;
let mut events = [EpollEvent::empty(); 1];
let fd_count = epoll_wait(poll_fd, &mut events, timeout_ms)?;
if fd_count == 0 {
Err(XQError::Timeout)
} else {
let bytes_written = stdin.read(buffer)?;
Ok(bytes_written)
}
}