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
use libc::{c_int, c_ushort};
use std::io;
#[cfg(target_os = "linux")]
pub const TIOCGWINSZ: usize = 0x0000_5413;
#[cfg(not(target_os = "linux"))]
pub const TIOCGWINSZ: usize = 0x4008_7468;
#[repr(C)]
struct TermSize {
row: c_ushort,
col: c_ushort,
_x: c_ushort,
_y: c_ushort,
}
#[cfg(target_env = "musl")]
fn tiocgwinsz() -> i32 {
TIOCGWINSZ as i32
}
#[cfg(all(not(target_env = "musl"), target_pointer_width = "64"))]
fn tiocgwinsz() -> u64 {
TIOCGWINSZ as u64
}
#[cfg(all(not(target_env = "musl"), target_pointer_width = "32"))]
fn tiocgwinsz() -> u32 {
TIOCGWINSZ as u32
}
pub fn terminal_size(fileno: c_int) -> io::Result<(u16, u16)> {
use libc::ioctl;
use std::mem;
unsafe {
let mut size: TermSize = mem::zeroed();
if ioctl(fileno, tiocgwinsz(), &mut size as *mut _) == 0 {
Ok((size.col as u16, size.row as u16))
} else {
Err(io::Error::new(
io::ErrorKind::Other,
"Unable to get the terminal size.",
))
}
}
}