diff --git a/src/unix_term.rs b/src/unix_term.rs index ec445d4b..d2d63013 100644 --- a/src/unix_term.rs +++ b/src/unix_term.rs @@ -157,21 +157,25 @@ fn poll_fd(fd: RawFd, timeout: i32) -> io::Result { events: libc::POLLIN, revents: 0, }; - let ret = unsafe { libc::poll(&mut pollfd as *mut _, 1, timeout) }; - if ret < 0 { - Err(io::Error::last_os_error()) - } else { - Ok(pollfd.revents & libc::POLLIN != 0) + loop { + let ret = unsafe { libc::poll(&mut pollfd as *mut _, 1, timeout) }; + if ret < 0 { + let err = io::Error::last_os_error(); + if err.kind() == io::ErrorKind::Interrupted { + continue; + } + break Err(err); + } + break Ok(pollfd.revents & libc::POLLIN != 0); } } #[cfg(target_os = "macos")] fn select_fd(fd: RawFd, timeout: i32) -> io::Result { - unsafe { - let mut read_fd_set: libc::fd_set = mem::zeroed(); - + loop { + let mut read_fd_set: libc::fd_set = unsafe { mem::zeroed() }; let mut timeout_val; - let timeout = if timeout < 0 { + let timeout_ptr: *mut libc::timeval = if timeout < 0 { ptr::null_mut() } else { timeout_val = libc::timeval { @@ -181,20 +185,25 @@ fn select_fd(fd: RawFd, timeout: i32) -> io::Result { &mut timeout_val }; - libc::FD_ZERO(&mut read_fd_set); - libc::FD_SET(fd, &mut read_fd_set); - let ret = libc::select( - fd + 1, - &mut read_fd_set, - ptr::null_mut(), - ptr::null_mut(), - timeout, - ); + let ret = unsafe { + libc::FD_ZERO(&mut read_fd_set); + libc::FD_SET(fd, &mut read_fd_set); + libc::select( + fd + 1, + &mut read_fd_set, + ptr::null_mut(), + ptr::null_mut(), + timeout_ptr, + ) + }; if ret < 0 { - Err(io::Error::last_os_error()) - } else { - Ok(libc::FD_ISSET(fd, &read_fd_set)) + let err = io::Error::last_os_error(); + if err.kind() == io::ErrorKind::Interrupted { + continue; + } + break Err(err); } + break Ok(unsafe { libc::FD_ISSET(fd, &read_fd_set) }); } } @@ -231,10 +240,18 @@ fn read_single_char(fd: RawFd) -> io::Result> { // If successful, return the number of bytes read. // Will return an error if nothing was read, i.e when called at end of file. fn read_bytes(fd: RawFd, buf: &mut [u8], count: u8) -> io::Result { - let read = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut _, count as usize) }; - if read < 0 { - Err(io::Error::last_os_error()) - } else if read == 0 { + let read = loop { + let n = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut _, count as usize) }; + if n < 0 { + let err = io::Error::last_os_error(); + if err.kind() == io::ErrorKind::Interrupted { + continue; + } + return Err(err); + } + break n; + }; + if read == 0 { Err(io::Error::new( io::ErrorKind::UnexpectedEof, "Reached end of file", diff --git a/src/windows_term/mod.rs b/src/windows_term/mod.rs index e3c7a277..846316cb 100644 --- a/src/windows_term/mod.rs +++ b/src/windows_term/mod.rs @@ -405,11 +405,9 @@ pub(crate) fn read_secure() -> io::Result { Key::Enter => { break; } - Key::Char('\x08') => { - if !rv.is_empty() { - let new_len = rv.len() - 1; - rv.truncate(new_len); - } + Key::Char('\x08') if !rv.is_empty() => { + let new_len = rv.len() - 1; + rv.truncate(new_len); } Key::Char(c) => { rv.push(c);