Skip to content

Commit 2d5c1a3

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. This also updates the minimum Rust version to 1.48, which is about as old as the previous minimum Rust version was when it was last updated. [I/O safety]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md [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 2d5c1a3

File tree

5 files changed

+19
-23
lines changed

5 files changed

+19
-23
lines changed

Diff for: 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"

Diff for: 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

Diff for: 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

Diff for: 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
//!

Diff for: 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)