Skip to content

Commit 098751c

Browse files
committed
Migrate from libc to rustix.
This migrates terminal_size from using libc directly to using rustix, which eliminates a few unsafe blocks and manual error handling. It does also add one new unsafe block, though this is because `terminal_size_using_fd` is a public safe function that has a `RawFd` argument. With [I/O safety], which is expected to be [stabilized in Rust 1.63], there will be new guidance saying be that [such functions should be unsafe]. It's not urgent to make any changes for this right now though. [I/O safety]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md [expected to be stabilized in Rust 1.63]: rust-lang/rust#87074 [such functions should be unsafe]: https://doc.rust-lang.org/nightly/std/os/unix/io/index.html
1 parent 0f36d74 commit 098751c

File tree

5 files changed

+19
-23
lines changed

5 files changed

+19
-23
lines changed

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ license = "MIT OR Apache-2.0"
1010
edition = "2018"
1111

1212

13-
[target.'cfg(not(windows))'.dependencies.libc]
14-
version = "0.2"
13+
[target.'cfg(not(windows))'.dependencies]
14+
rustix = { version = "0.35.6", features = ["termios"] }
1515

1616
[target.'cfg(windows)'.dependencies.winapi]
1717
version = "0.3"

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ if let Some((Width(w), Height(h))) = size {
2222

2323
## Minimum Rust Version
2424

25-
This crate requires a minimum rust version of 1.31.0 (2018-12-06)
25+
This crate requires a minimum rust version of 1.48.0 (2020-11-19)
2626

2727
## License
2828

examples/get_size.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,19 @@ fn run() {
2525

2626
#[cfg(not(windows))]
2727
fn run() {
28+
use std::os::unix::io::AsRawFd;
29+
2830
println!(
2931
"Size from terminal_size_using_fd(stdout): {:?}",
30-
terminal_size::terminal_size_using_fd(libc::STDOUT_FILENO)
32+
terminal_size::terminal_size_using_fd(std::io::stdout().as_raw_fd())
3133
);
3234
println!(
3335
"Size from terminal_size_using_fd(stderr): {:?}",
34-
terminal_size::terminal_size_using_fd(libc::STDERR_FILENO)
36+
terminal_size::terminal_size_using_fd(std::io::stderr().as_raw_fd())
3537
);
3638
println!(
3739
"Size from terminal_size_using_fd(stdin): {:?}",
38-
terminal_size::terminal_size_using_fd(libc::STDIN_FILENO)
40+
terminal_size::terminal_size_using_fd(std::io::stdin().as_raw_fd())
3941
);
4042
}
4143

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! Supports both Linux, MacOS, and Windows.
44
//!
5-
//! This crate requires a minimum rust version of 1.31.0 (2018-12-06)
5+
//! This crate requires a minimum rust version of 1.48.0 (2020-11-19)
66
//!
77
//! # Example
88
//!

src/unix.rs

+10-16
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,31 @@
11
use super::{Height, Width};
22
use std::os::unix::io::RawFd;
3+
use rustix::fd::{BorrowedFd, AsRawFd};
34

45
/// Returns the size of the terminal defaulting to STDOUT, if available.
56
///
67
/// If STDOUT is not a tty, returns `None`
78
pub fn terminal_size() -> Option<(Width, Height)> {
8-
terminal_size_using_fd(libc::STDOUT_FILENO)
9+
terminal_size_using_fd(std::io::stdout().as_raw_fd())
910
}
1011

1112
/// Returns the size of the terminal using the given file descriptor, if available.
1213
///
1314
/// If the given file descriptor is not a tty, returns `None`
1415
pub fn terminal_size_using_fd(fd: RawFd) -> Option<(Width, Height)> {
15-
use libc::ioctl;
16-
use libc::isatty;
17-
use libc::{winsize as WinSize, TIOCGWINSZ};
18-
let is_tty: bool = unsafe { isatty(fd) == 1 };
16+
use rustix::termios::{isatty, tcgetwinsize};
1917

20-
if !is_tty {
21-
return None;
22-
}
18+
// TODO: Once I/O safety is stabilized, the enlosing function here should
19+
// be unsafe due to taking a `RawFd`. We should then move the main
20+
// logic here into a new function which takes a `BorrowedFd` and is safe.
21+
let fd = unsafe { BorrowedFd::borrow_raw(fd) };
2322

24-
let mut winsize = WinSize {
25-
ws_row: 0,
26-
ws_col: 0,
27-
ws_xpixel: 0,
28-
ws_ypixel: 0,
29-
};
30-
31-
if unsafe { ioctl(fd, TIOCGWINSZ.into(), &mut winsize) } == -1 {
23+
if !isatty(fd) {
3224
return None;
3325
}
3426

27+
let winsize = tcgetwinsize(fd).ok()?;
28+
3529
let rows = winsize.ws_row;
3630
let cols = winsize.ws_col;
3731

0 commit comments

Comments
 (0)