diff options
author | Andrew Gallant <jamslam@gmail.com> | 2017-01-15 16:32:30 -0500 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2017-01-15 16:32:30 -0500 |
commit | f5a2d022ecd16dfe67ea829267e9220136f20167 (patch) | |
tree | 0d0683b39a2f352b1dee63bed4216c486ed28b20 /src | |
parent | b1d1cd2366ba8d3e40a312ba79ff7078a97165f5 (diff) |
Replace internal atty module with atty crate.
This removes all use of explicit unsafe in ripgrep proper except for
one: accessing the contents of a memory map. (Which may never go away.)
Diffstat (limited to 'src')
-rw-r--r-- | src/args.rs | 33 | ||||
-rw-r--r-- | src/atty.rs | 145 | ||||
-rw-r--r-- | src/main.rs | 2 |
3 files changed, 28 insertions, 152 deletions
diff --git a/src/args.rs b/src/args.rs index eeccb184..15184d4e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -394,8 +394,8 @@ impl<'a> ArgMatches<'a> { self.values_of_os("file").map_or(false, |mut files| { files.any(|f| f == "-") }); - let search_cwd = atty::on_stdin() - || !atty::stdin_is_readable() + let search_cwd = atty::is(atty::Stream::Stdin) + || !stdin_is_readable() || (self.is_present("file") && file_is_stdin) || self.is_present("files") || self.is_present("type-list"); @@ -584,7 +584,7 @@ impl<'a> ArgMatches<'a> { } else { self.is_present("line-number") || self.is_present("column") - || atty::on_stdout() + || atty::is(atty::Stream::Stdout) || self.is_present("pretty") || self.is_present("vimgrep") } @@ -602,7 +602,7 @@ impl<'a> ArgMatches<'a> { false } else { self.is_present("heading") - || atty::on_stdout() + || atty::is(atty::Stream::Stdout) || self.is_present("pretty") } } @@ -667,7 +667,7 @@ impl<'a> ArgMatches<'a> { } else if self.is_present("vimgrep") { false } else if preference == "auto" { - atty::on_stdout() || self.is_present("pretty") + atty::is(atty::Stream::Stdout) || self.is_present("pretty") } else { false } @@ -687,7 +687,7 @@ impl<'a> ArgMatches<'a> { } else if self.is_present("vimgrep") { termcolor::ColorChoice::Never } else if preference == "auto" { - if atty::on_stdout() || self.is_present("pretty") { + if atty::is(atty::Stream::Stdout) || self.is_present("pretty") { termcolor::ColorChoice::Auto } else { termcolor::ColorChoice::Never @@ -869,3 +869,24 @@ impl QuietMatched { } } } + +/// Returns true if and only if stdin is deemed searchable. +#[cfg(unix)] +fn stdin_is_readable() -> bool { + use std::os::unix::fs::FileTypeExt; + use same_file::Handle; + + let ft = match Handle::stdin().and_then(|h| h.as_file().metadata()) { + Err(_) => return false, + Ok(md) => md.file_type(), + }; + ft.is_file() || ft.is_fifo() +} + +/// Returns true if and only if stdin is deemed searchable. +#[cfg(windows)] +fn stdin_is_readable() -> bool { + // On Windows, it's not clear what the possibilities are to me, so just + // always return true. + true +} diff --git a/src/atty.rs b/src/atty.rs deleted file mode 100644 index cb10c1dc..00000000 --- a/src/atty.rs +++ /dev/null @@ -1,145 +0,0 @@ -/*! -This atty module contains functions for detecting whether ripgrep is being fed -from (or to) a terminal. Windows and Unix do this differently, so implement -both here. -*/ - -#[cfg(windows)] -use winapi::minwindef::DWORD; -#[cfg(windows)] -use winapi::winnt::HANDLE; - -#[cfg(unix)] -pub fn stdin_is_readable() -> bool { - use std::os::unix::fs::FileTypeExt; - use same_file::Handle; - - let ft = match Handle::stdin().and_then(|h| h.as_file().metadata()) { - Err(_) => return false, - Ok(md) => md.file_type(), - }; - ft.is_file() || ft.is_fifo() -} - -#[cfg(windows)] -pub fn stdin_is_readable() -> bool { - // ??? - true -} - -/// Returns true if there is a tty on stdin. -#[cfg(unix)] -pub fn on_stdin() -> bool { - use libc; - 0 < unsafe { libc::isatty(libc::STDIN_FILENO) } -} - -/// Returns true if there is a tty on stdout. -#[cfg(unix)] -pub fn on_stdout() -> bool { - use libc; - 0 < unsafe { libc::isatty(libc::STDOUT_FILENO) } -} - -/// Returns true if there is a tty on stdin. -#[cfg(windows)] -pub fn on_stdin() -> bool { - use kernel32::GetStdHandle; - use winapi::winbase::{ - STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE, - }; - - unsafe { - let stdin = GetStdHandle(STD_INPUT_HANDLE); - if console_on_handle(stdin) { - // False positives aren't possible. If we got a console then - // we definitely have a tty on stdin. - return true; - } - // Otherwise, it's possible to get a false negative. If we know that - // there's a console on stdout or stderr however, then this is a true - // negative. - if console_on_fd(STD_OUTPUT_HANDLE) - || console_on_fd(STD_ERROR_HANDLE) { - return false; - } - // Otherwise, we can't really tell, so we do a weird hack. - msys_tty_on_handle(stdin) - } -} - -/// Returns true if there is a tty on stdout. -#[cfg(windows)] -pub fn on_stdout() -> bool { - use kernel32::GetStdHandle; - use winapi::winbase::{ - STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE, - }; - - unsafe { - let stdout = GetStdHandle(STD_OUTPUT_HANDLE); - if console_on_handle(stdout) { - // False positives aren't possible. If we got a console then - // we definitely have a tty on stdout. - return true; - } - // Otherwise, it's possible to get a false negative. If we know that - // there's a console on stdin or stderr however, then this is a true - // negative. - if console_on_fd(STD_INPUT_HANDLE) || console_on_fd(STD_ERROR_HANDLE) { - return false; - } - // Otherwise, we can't really tell, so we do a weird hack. - msys_tty_on_handle(stdout) - } -} - -/// Returns true if there is an MSYS tty on the given handle. -#[cfg(windows)] -unsafe fn msys_tty_on_handle(handle: HANDLE) -> bool { - use std::ffi::OsString; - use std::mem; - use std::os::raw::c_void; - use std::os::windows::ffi::OsStringExt; - use std::slice; - - use kernel32::{GetFileInformationByHandleEx}; - use winapi::fileapi::FILE_NAME_INFO; - use winapi::minwinbase::FileNameInfo; - use winapi::minwindef::MAX_PATH; - - let size = mem::size_of::<FILE_NAME_INFO>(); - let mut name_info_bytes = vec![0u8; size + MAX_PATH]; - let res = GetFileInformationByHandleEx( - handle, - FileNameInfo, - &mut *name_info_bytes as *mut _ as *mut c_void, - name_info_bytes.len() as u32); - if res == 0 { - return true; - } - let name_info: FILE_NAME_INFO = - *(name_info_bytes[0..size].as_ptr() as *const FILE_NAME_INFO); - let name_bytes = - &name_info_bytes[size..size + name_info.FileNameLength as usize]; - let name_u16 = slice::from_raw_parts( - name_bytes.as_ptr() as *const u16, name_bytes.len() / 2); - let name = OsString::from_wide(name_u16) - .as_os_str().to_string_lossy().into_owned(); - name.contains("msys-") || name.contains("-pty") -} - -/// Returns true if there is a console on the given file descriptor. -#[cfg(windows)] -unsafe fn console_on_fd(fd: DWORD) -> bool { - use kernel32::GetStdHandle; - console_on_handle(GetStdHandle(fd)) -} - -/// Returns true if there is a console on the given handle. -#[cfg(windows)] -unsafe fn console_on_handle(handle: HANDLE) -> bool { - use kernel32::GetConsoleMode; - let mut out = 0; - GetConsoleMode(handle, &mut out) != 0 -} diff --git a/src/main.rs b/src/main.rs index 735298f9..66860d14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +extern crate atty; extern crate bytecount; #[macro_use] extern crate clap; @@ -46,7 +47,6 @@ macro_rules! eprintln { mod app; mod args; -mod atty; mod pathutil; mod printer; mod search_buffer; |