summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2017-01-15 16:32:30 -0500
committerAndrew Gallant <jamslam@gmail.com>2017-01-15 16:32:30 -0500
commitf5a2d022ecd16dfe67ea829267e9220136f20167 (patch)
tree0d0683b39a2f352b1dee63bed4216c486ed28b20
parentb1d1cd2366ba8d3e40a312ba79ff7078a97165f5 (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.)
-rw-r--r--Cargo.lock12
-rw-r--r--Cargo.toml1
-rw-r--r--src/args.rs33
-rw-r--r--src/atty.rs145
-rw-r--r--src/main.rs2
5 files changed, 41 insertions, 152 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 703b8c88..b768d505 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,7 @@
name = "ripgrep"
version = "0.4.0"
dependencies = [
+ "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -34,6 +35,16 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "atty"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "bitflags"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -313,6 +324,7 @@ dependencies = [
[metadata]
"checksum aho-corasick 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f660b942762979b56c9f07b4b36bb559776fbad102f05d6771e1b629e8fd5bf"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
+"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e8f09fbc8c6726a4b616dcfbd4f54491068d6bb1b93ac03c78ac18ff9a5924a"
"checksum clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)" = "95b78f3fe0fc94c13c731714363260e04b557a637166f33a4570d3189d642374"
diff --git a/Cargo.toml b/Cargo.toml
index b65e1368..da1c9d2b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,6 +25,7 @@ name = "integration"
path = "tests/tests.rs"
[dependencies]
+atty = "0.2.2"
bytecount = "0.1.4"
clap = "2.19.0"
env_logger = { version = "0.3", default-features = false }
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;