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
use std::cell::RefCell;
use std::fs::File;
use std::io;
use std::rc::Rc;
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum ExitStatus {
Exited(u32),
Signaled(u8),
Other(i32),
Undetermined,
}
impl ExitStatus {
pub fn success(self) -> bool {
if let ExitStatus::Exited(0) = self {
true
} else {
false
}
}
}
#[derive(Debug, Copy, Clone)]
#[allow(dead_code)]
pub enum StandardStream {
Input = 0,
Output = 1,
Error = 2,
}
thread_local! {
static STREAMS: RefCell<[Option<Rc<File>>; 3]> = RefCell::default();
}
#[cfg(unix)]
use crate::posix::make_standard_stream;
#[cfg(windows)]
use crate::win32::make_standard_stream;
pub fn get_standard_stream(which: StandardStream) -> io::Result<Rc<File>> {
STREAMS.with(|streams| {
if let Some(ref stream) = streams.borrow()[which as usize] {
return Ok(Rc::clone(&stream));
}
let stream = make_standard_stream(which)?;
streams.borrow_mut()[which as usize] = Some(Rc::clone(&stream));
Ok(stream)
})
}