Skip to content

Commit 5307747

Browse files
authored
Merge pull request #66 from sunfishcode/main
Update the API for I/O safety
2 parents 78e81fa + a29b904 commit 5307747

File tree

4 files changed

+62
-69
lines changed

4 files changed

+62
-69
lines changed

examples/get_size.rs

+9-42
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,19 @@
1-
#[cfg(windows)]
2-
fn run() {
3-
use std::os::windows::io::RawHandle;
4-
use windows_sys::Win32::System::Console::{
5-
GetStdHandle, STD_ERROR_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
6-
};
7-
8-
let stdout = unsafe { GetStdHandle(STD_OUTPUT_HANDLE) } as RawHandle;
9-
println!(
10-
"Size from terminal_size_using_handle(stdout): {:?}",
11-
terminal_size::terminal_size_using_handle(stdout)
12-
);
13-
14-
let stderr = unsafe { GetStdHandle(STD_ERROR_HANDLE) } as RawHandle;
15-
println!(
16-
"Size from terminal_size_using_handle(stderr): {:?}",
17-
terminal_size::terminal_size_using_handle(stderr)
18-
);
19-
20-
let stdin = unsafe { GetStdHandle(STD_INPUT_HANDLE) } as RawHandle;
1+
fn main() {
212
println!(
22-
"Size from terminal_size_using_handle(stdin): {:?}",
23-
terminal_size::terminal_size_using_handle(stdin)
3+
"Size from terminal_size(): {:?}",
4+
terminal_size::terminal_size()
245
);
25-
}
26-
27-
#[cfg(not(windows))]
28-
fn run() {
29-
use std::os::unix::io::AsRawFd;
306

317
println!(
32-
"Size from terminal_size_using_fd(stdout): {:?}",
33-
terminal_size::terminal_size_using_fd(std::io::stdout().as_raw_fd())
8+
"Size from terminal_size_of(stdout): {:?}",
9+
terminal_size::terminal_size_of(std::io::stdout())
3410
);
3511
println!(
36-
"Size from terminal_size_using_fd(stderr): {:?}",
37-
terminal_size::terminal_size_using_fd(std::io::stderr().as_raw_fd())
12+
"Size from terminal_size_of(stderr): {:?}",
13+
terminal_size::terminal_size_of(std::io::stderr())
3814
);
3915
println!(
40-
"Size from terminal_size_using_fd(stdin): {:?}",
41-
terminal_size::terminal_size_using_fd(std::io::stdin().as_raw_fd())
42-
);
43-
}
44-
45-
fn main() {
46-
println!(
47-
"Size from terminal_size(): {:?}",
48-
terminal_size::terminal_size()
16+
"Size from terminal_size_of(stdin): {:?}",
17+
terminal_size::terminal_size_of(std::io::stdin())
4918
);
50-
51-
run();
5219
}

src/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ pub struct Height(pub u16);
2626
#[cfg(unix)]
2727
mod unix;
2828
#[cfg(unix)]
29-
pub use crate::unix::{terminal_size, terminal_size_using_fd};
29+
#[allow(deprecated)]
30+
pub use crate::unix::{terminal_size, terminal_size_of, terminal_size_using_fd};
3031

3132
#[cfg(windows)]
3233
mod windows;
3334
#[cfg(windows)]
34-
pub use crate::windows::{terminal_size, terminal_size_using_handle};
35+
#[allow(deprecated)]
36+
pub use crate::windows::{terminal_size, terminal_size_of, terminal_size_using_handle};
3537

3638
#[cfg(not(any(unix, windows)))]
3739
pub fn terminal_size() -> Option<(Width, Height)> {

src/unix.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
use super::{Height, Width};
2-
use rustix::fd::{BorrowedFd, AsRawFd};
3-
use std::os::unix::io::RawFd;
2+
use std::os::unix::io::{AsFd, BorrowedFd, RawFd};
43

54
/// Returns the size of the terminal.
65
///
76
/// This function checks the stdout, stderr, and stdin streams (in that order).
87
/// The size of the first stream that is a TTY will be returned. If nothing
98
/// is a TTY, then `None` is returned.
109
pub fn terminal_size() -> Option<(Width, Height)> {
11-
if let Some(size) = terminal_size_using_fd(std::io::stdout().as_raw_fd()) {
10+
if let Some(size) = terminal_size_of(std::io::stdout()) {
1211
Some(size)
13-
} else if let Some(size) = terminal_size_using_fd(std::io::stderr().as_raw_fd()) {
12+
} else if let Some(size) = terminal_size_of(std::io::stderr()) {
1413
Some(size)
15-
} else if let Some(size) = terminal_size_using_fd(std::io::stdin().as_raw_fd()) {
14+
} else if let Some(size) = terminal_size_of(std::io::stdin()) {
1615
Some(size)
1716
} else {
1817
None
@@ -22,19 +21,14 @@ pub fn terminal_size() -> Option<(Width, Height)> {
2221
/// Returns the size of the terminal using the given file descriptor, if available.
2322
///
2423
/// If the given file descriptor is not a tty, returns `None`
25-
pub fn terminal_size_using_fd(fd: RawFd) -> Option<(Width, Height)> {
24+
pub fn terminal_size_of<Fd: AsFd>(fd: Fd) -> Option<(Width, Height)> {
2625
use rustix::termios::{isatty, tcgetwinsize};
2726

28-
// TODO: Once I/O safety is stabilized, the enlosing function here should
29-
// be unsafe due to taking a `RawFd`. We should then move the main
30-
// logic here into a new function which takes a `BorrowedFd` and is safe.
31-
let fd = unsafe { BorrowedFd::borrow_raw(fd) };
32-
33-
if !isatty(fd) {
27+
if !isatty(&fd) {
3428
return None;
3529
}
3630

37-
let winsize = tcgetwinsize(fd).ok()?;
31+
let winsize = tcgetwinsize(&fd).ok()?;
3832

3933
let rows = winsize.ws_row;
4034
let cols = winsize.ws_col;
@@ -46,6 +40,21 @@ pub fn terminal_size_using_fd(fd: RawFd) -> Option<(Width, Height)> {
4640
}
4741
}
4842

43+
/// Returns the size of the terminal using the given raw file descriptor, if available.
44+
///
45+
/// The given file descriptor must be an open file descriptor.
46+
///
47+
/// If the given file descriptor is not a tty, returns `None`
48+
///
49+
/// # Safety
50+
///
51+
/// `fd` must be a valid open file descriptor.
52+
#[deprecated(note = "Use `terminal_size_of` instead.
53+
Use `BorrowedFd::borrow_raw` to convert a raw fd into a `BorrowedFd` if needed.")]
54+
pub unsafe fn terminal_size_using_fd(fd: RawFd) -> Option<(Width, Height)> {
55+
terminal_size_of(BorrowedFd::borrow_raw(fd))
56+
}
57+
4958
#[test]
5059
/// Compare with the output of `stty size`
5160
fn compare_with_stty() {

src/windows.rs

+27-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{Height, Width};
2-
use std::os::windows::io::RawHandle;
2+
use std::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, RawHandle};
33

44
/// Returns the size of the terminal.
55
///
@@ -14,17 +14,17 @@ pub fn terminal_size() -> Option<(Width, Height)> {
1414
GetStdHandle, STD_ERROR_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
1515
};
1616

17-
if let Some(size) =
18-
terminal_size_using_handle(unsafe { GetStdHandle(STD_OUTPUT_HANDLE) as RawHandle })
19-
{
17+
if let Some(size) = terminal_size_of(unsafe {
18+
BorrowedHandle::borrow_raw(GetStdHandle(STD_OUTPUT_HANDLE) as RawHandle)
19+
}) {
2020
Some(size)
21-
} else if let Some(size) =
22-
terminal_size_using_handle(unsafe { GetStdHandle(STD_ERROR_HANDLE) as RawHandle })
23-
{
21+
} else if let Some(size) = terminal_size_of(unsafe {
22+
BorrowedHandle::borrow_raw(GetStdHandle(STD_ERROR_HANDLE) as RawHandle)
23+
}) {
2424
Some(size)
25-
} else if let Some(size) =
26-
terminal_size_using_handle(unsafe { GetStdHandle(STD_INPUT_HANDLE) as RawHandle })
27-
{
25+
} else if let Some(size) = terminal_size_of(unsafe {
26+
BorrowedHandle::borrow_raw(GetStdHandle(STD_INPUT_HANDLE) as RawHandle)
27+
}) {
2828
Some(size)
2929
} else {
3030
None
@@ -34,14 +34,14 @@ pub fn terminal_size() -> Option<(Width, Height)> {
3434
/// Returns the size of the terminal using the given handle, if available.
3535
///
3636
/// If the given handle is not a tty, returns `None`
37-
pub fn terminal_size_using_handle(handle: RawHandle) -> Option<(Width, Height)> {
37+
pub fn terminal_size_of<Handle: AsHandle>(handle: Handle) -> Option<(Width, Height)> {
3838
use windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE;
3939
use windows_sys::Win32::System::Console::{
4040
GetConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT,
4141
};
4242

4343
// convert between windows_sys::Win32::Foundation::HANDLE and std::os::windows::raw::HANDLE
44-
let hand = handle as windows_sys::Win32::Foundation::HANDLE;
44+
let hand = handle.as_handle().as_raw_handle() as windows_sys::Win32::Foundation::HANDLE;
4545

4646
if hand == INVALID_HANDLE_VALUE {
4747
return None;
@@ -68,3 +68,18 @@ pub fn terminal_size_using_handle(handle: RawHandle) -> Option<(Width, Height)>
6868
let h: Height = Height((csbi.srWindow.Bottom - csbi.srWindow.Top + 1) as u16);
6969
Some((w, h))
7070
}
71+
72+
/// Returns the size of the terminal using the given handle, if available.
73+
///
74+
/// The given handle must be an open handle.
75+
///
76+
/// If the given handle is not a tty, returns `None`
77+
///
78+
/// # Safety
79+
///
80+
/// `handle` must be a valid open file handle.
81+
#[deprecated(note = "Use `terminal_size_of` instead.
82+
Use `BorrowedHandle::borrow_raw` to convert a raw handle into a `BorrowedHandle` if needed.")]
83+
pub unsafe fn terminal_size_using_handle(handle: RawHandle) -> Option<(Width, Height)> {
84+
terminal_size_of(BorrowedHandle::borrow_raw(handle))
85+
}

0 commit comments

Comments
 (0)