-
Notifications
You must be signed in to change notification settings - Fork 4
/
stdin_hack.rs
56 lines (46 loc) · 1.65 KB
/
stdin_hack.rs
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
// (C) Copyright 2019 Hewlett Packard Enterprise Development LP
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender};
use std::thread::{self, JoinHandle};
use simple_error::{SimpleError, SimpleResult};
use crate::config::Config;
use crate::renderer::LogEntry;
/// reads the process stdin directly using Evil Hacks to ensure our fd doesn't
/// get closed when the interactive UI opens /dev/tty
/// for some reason opening /dev/tty closes our stdin pipe even though it still
/// technically remains readable at /dev/stdin
/// note that this _probably_ only works on linux, other OSes may need to run
/// their application via a subprocess or just fall back to the styled renderer
pub fn read_stdin_hack(
config: Arc<Config>,
tx: Sender<LogEntry>,
_exit_req_rx: Receiver<()>,
_exit_resp_tx: Sender<()>
) -> JoinHandle<SimpleResult<()>> {
thread::Builder::new().name("read_stdin_hack".to_string()).spawn(move || {
let file = File::open("/dev/stdin").map_err(SimpleError::from)?;
let mut empty = true;
for line in BufReader::new(file).lines() {
let line = line.map_err(SimpleError::from)?;
empty = false;
match LogEntry::message(Arc::clone(&config), &line, None) {
Ok(Some(entry)) => match tx.send(entry) {
Ok(_) => (),
Err(_) => break
},
Err(_) => continue,
_ => continue
}
}
if empty {
tx.send(LogEntry::internal(
"warning: reached end of input without reading any messages"
)).ok();
}
// not much we can do if this fails
tx.send(LogEntry::eof()).ok();
Ok(())
}).unwrap()
}