Skip to content

Commit 85c4de4

Browse files
authored
More reliably reset raw mode (#171)
1 parent 55e4762 commit 85c4de4

File tree

2 files changed

+26
-23
lines changed

2 files changed

+26
-23
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Set an appropriate lower version of libc for macos changes.
88
* Improved behavior of `read_single_key` so it does not disturb other
99
threads quite as much. (#165)
10+
* More reliably reset raw mode in terminal.
1011

1112
## 0.15.6
1213

src/unix_term.rs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -202,28 +202,8 @@ fn read_bytes(fd: i32, buf: &mut [u8], count: u8) -> io::Result<u8> {
202202
}
203203
}
204204

205-
pub fn read_single_key() -> io::Result<Key> {
206-
let tty_f;
207-
let fd = unsafe {
208-
if libc::isatty(libc::STDIN_FILENO) == 1 {
209-
libc::STDIN_FILENO
210-
} else {
211-
tty_f = fs::OpenOptions::new()
212-
.read(true)
213-
.write(true)
214-
.open("/dev/tty")?;
215-
tty_f.as_raw_fd()
216-
}
217-
};
218-
let mut termios = core::mem::MaybeUninit::uninit();
219-
c_result(|| unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) })?;
220-
let mut termios = unsafe { termios.assume_init() };
221-
let original = termios;
222-
unsafe { libc::cfmakeraw(&mut termios) };
223-
termios.c_oflag = original.c_oflag;
224-
c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &termios) })?;
225-
226-
let rv: io::Result<Key> = loop {
205+
fn read_single_key_impl(fd: i32) -> Result<Key, io::Error> {
206+
loop {
227207
match read_single_char(fd)? {
228208
Some('\x1b') => {
229209
// Escape was read, keep reading in case we find a familiar key
@@ -312,8 +292,30 @@ pub fn read_single_key() -> io::Result<Key> {
312292
}
313293
}
314294
}
315-
};
295+
}
296+
}
316297

298+
pub fn read_single_key() -> io::Result<Key> {
299+
let tty_f;
300+
let fd = unsafe {
301+
if libc::isatty(libc::STDIN_FILENO) == 1 {
302+
libc::STDIN_FILENO
303+
} else {
304+
tty_f = fs::OpenOptions::new()
305+
.read(true)
306+
.write(true)
307+
.open("/dev/tty")?;
308+
tty_f.as_raw_fd()
309+
}
310+
};
311+
let mut termios = core::mem::MaybeUninit::uninit();
312+
c_result(|| unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) })?;
313+
let mut termios = unsafe { termios.assume_init() };
314+
let original = termios;
315+
unsafe { libc::cfmakeraw(&mut termios) };
316+
termios.c_oflag = original.c_oflag;
317+
c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &termios) })?;
318+
let rv: io::Result<Key> = read_single_key_impl(fd);
317319
c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &original) })?;
318320

319321
// if the user hit ^C we want to signal SIGINT to outselves.

0 commit comments

Comments
 (0)