atty-0.2.13/.gitignore010064400007650000024000000000271276542054100127720ustar0000000000000000target Cargo.lock *.bk atty-0.2.13/Cargo.toml.orig010064400007650000024000000012661351324037600136750ustar0000000000000000[package] name = "atty" version = "0.2.13" authors = ["softprops "] description = "A simple interface for querying atty" documentation = "http://softprops.github.io/atty" homepage = "https://github.com/softprops/atty" repository = "https://github.com/softprops/atty" keywords = ["terminal", "tty", "isatty"] license = "MIT" readme = "README.md" exclude = ["/.travis.yml", "/appveyor.yml"] [badges] travis-ci = { repository = "softprops/atty" } [target.'cfg(unix)'.dependencies] libc = { version = "0.2", default-features = false } [target.'cfg(windows)'.dependencies.winapi] version = "0.3" features = ["consoleapi", "processenv", "minwinbase", "minwindef", "winbase"] atty-0.2.13/Cargo.toml0000644000000022620000000000000101370ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "atty" version = "0.2.13" authors = ["softprops "] exclude = ["/.travis.yml", "/appveyor.yml"] description = "A simple interface for querying atty" homepage = "https://github.com/softprops/atty" documentation = "http://softprops.github.io/atty" readme = "README.md" keywords = ["terminal", "tty", "isatty"] license = "MIT" repository = "https://github.com/softprops/atty" [target."cfg(unix)".dependencies.libc] version = "0.2" default-features = false [target."cfg(windows)".dependencies.winapi] version = "0.3" features = ["consoleapi", "processenv", "minwinbase", "minwindef", "winbase"] [badges.travis-ci] repository = "softprops/atty" atty-0.2.13/CHANGELOG.md010064400007650000024000000027501351324037600126160ustar0000000000000000# 0.2.13 * support older versions of rust that do now support 2018 edition # 0.2.12 * Redox is now in the unix family so redox cfg is no longer needed [#35](https://github.com/softprops/atty/pull/35) # 0.2.11 * fix msys detection with `winapi@0.3.5` [#28](https://github.com/softprops/atty/pull/28) # 0.2.10 * fix wasm regression [#27](https://github.com/softprops/atty/pull/27) # 0.2.9 * Fix fix pty detection [#25](https://github.com/softprops/atty/pull/25) # 0.2.8 * Fix an inverted condition on MinGW [#22](https://github.com/softprops/atty/pull/22) # 0.2.7 * Change `||` to `&&` for whether MSYS is a tty [#24](https://github.com/softprops/atty/pull/24/) # 0.2.6 * updated winapi dependency to [0.3](https://retep998.github.io/blog/winapi-0.3/) [#18](https://github.com/softprops/atty/pull/18) # 0.2.5 * added support for Wasm compile targets [#17](https://github.com/softprops/atty/pull/17) # 0.2.4 * added support for Wasm compile targets [#17](https://github.com/softprops/atty/pull/17) # 0.2.3 * added support for Redox OS [#14](https://github.com/softprops/atty/pull/14) # 0.2.2 * use target specific dependencies [#11](https://github.com/softprops/atty/pull/11) * Add tty detection for MSYS terminals [#12](https://github.com/softprops/atty/pull/12) # 0.2.1 * fix windows bug # 0.2.0 * support for various stream types # 0.1.2 * windows support (with automated testing) * automated code coverage # 0.1.1 * bumped libc dep from `0.1` to `0.2` # 0.1.0 * initial release atty-0.2.13/examples/atty.rs010064400007650000024000000003111351323562000141350ustar0000000000000000extern crate atty; use atty::{is, Stream}; fn main() { println!("stdout? {}", is(Stream::Stdout)); println!("stderr? {}", is(Stream::Stderr)); println!("stdin? {}", is(Stream::Stdin)); } atty-0.2.13/LICENSE010064400007650000024000000020451351174326400120110ustar0000000000000000Copyright (c) 2015-2019 Doug Tangren Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. atty-0.2.13/README.md010064400007650000024000000033001351174325400122550ustar0000000000000000# atty [![Build Status](https://travis-ci.org/softprops/atty.svg?branch=master)](https://travis-ci.org/softprops/atty) [![Build status](https://ci.appveyor.com/api/projects/status/geggrsnsjsuse8cv?svg=true)](https://ci.appveyor.com/project/softprops/atty) [![Coverage Status](https://coveralls.io/repos/softprops/atty/badge.svg?branch=master&service=github)](https://coveralls.io/github/softprops/atty?branch=master) [![crates.io](https://img.shields.io/crates/v/atty.svg)](https://crates.io/crates/atty) [![Released API docs](https://docs.rs/atty/badge.svg)](http://docs.rs/atty) [![Master API docs](https://img.shields.io/badge/docs-master-green.svg)](https://softprops.github.io/atty) > are you or are you not a tty? ## install Add the following to your `Cargo.toml` ```toml [dependencies] atty = "0.2" ``` ## usage ```rust use atty::Stream; fn main() { if atty::is(Stream::Stdout) { println!("I'm a terminal"); } else { println!("I'm not"); } } ``` ## testing This library has been unit tested on both unix and windows platforms (via appveyor). A simple example program is provided in this repo to test various tty's. By default. It prints ```bash $ cargo run --example atty stdout? true stderr? true stdin? true ``` To test std in, pipe some text to the program ```bash $ echo "test" | cargo run --example atty stdout? true stderr? true stdin? false ``` To test std out, pipe the program to something ```bash $ cargo run --example atty | grep std stdout? false stderr? true stdin? true ``` To test std err, pipe the program to something redirecting std err ```bash $ cargo run --example atty 2>&1 | grep std stdout? false stderr? false stdin? true ``` Doug Tangren (softprops) 2015-2019 atty-0.2.13/rustfmt.toml010064400007650000024000000003271351174245600134100ustar0000000000000000# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#fn_args_layout fn_args_layout = "Vertical" # https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#merge_imports merge_imports = trueatty-0.2.13/src/lib.rs010064400007650000024000000117651351323562000127120ustar0000000000000000//! atty is a simple utility that answers one question //! > is this a tty? //! //! usage is just as simple //! //! ``` //! if atty::is(atty::Stream::Stdout) { //! println!("i'm a tty") //! } //! ``` //! //! ``` //! if atty::isnt(atty::Stream::Stdout) { //! println!("i'm not a tty") //! } //! ``` #![cfg_attr(unix, no_std)] #[cfg(unix)] extern crate libc; #[cfg(windows)] extern crate winapi; #[cfg(windows)] use winapi::shared::minwindef::DWORD; #[cfg(windows)] use winapi::shared::ntdef::WCHAR; /// possible stream sources #[derive(Clone, Copy, Debug)] pub enum Stream { Stdout, Stderr, Stdin, } /// returns true if this is a tty #[cfg(all(unix, not(target_arch = "wasm32")))] pub fn is(stream: Stream) -> bool { extern crate libc; let fd = match stream { Stream::Stdout => libc::STDOUT_FILENO, Stream::Stderr => libc::STDERR_FILENO, Stream::Stdin => libc::STDIN_FILENO, }; unsafe { libc::isatty(fd) != 0 } } /// returns true if this is a tty #[cfg(windows)] pub fn is(stream: Stream) -> bool { use winapi::um::winbase::{ STD_ERROR_HANDLE as STD_ERROR, STD_INPUT_HANDLE as STD_INPUT, STD_OUTPUT_HANDLE as STD_OUTPUT, }; let (fd, others) = match stream { Stream::Stdin => (STD_INPUT, [STD_ERROR, STD_OUTPUT]), Stream::Stderr => (STD_ERROR, [STD_INPUT, STD_OUTPUT]), Stream::Stdout => (STD_OUTPUT, [STD_INPUT, STD_ERROR]), }; if unsafe { console_on_any(&[fd]) } { // False positives aren't possible. If we got a console then // we definitely have a tty on stdin. return true; } // At this point, we *could* have a false negative. We can determine that // this is true negative if we can detect the presence of a console on // any of the other streams. If another stream has a console, then we know // we're in a Windows console and can therefore trust the negative. if unsafe { console_on_any(&others) } { return false; } // Otherwise, we fall back to a very strange msys hack to see if we can // sneakily detect the presence of a tty. unsafe { msys_tty_on(fd) } } /// returns true if this is _not_ a tty pub fn isnt(stream: Stream) -> bool { !is(stream) } /// Returns true if any of the given fds are on a console. #[cfg(windows)] unsafe fn console_on_any(fds: &[DWORD]) -> bool { use winapi::um::{consoleapi::GetConsoleMode, processenv::GetStdHandle}; for &fd in fds { let mut out = 0; let handle = GetStdHandle(fd); if GetConsoleMode(handle, &mut out) != 0 { return true; } } false } /// Returns true if there is an MSYS tty on the given handle. #[cfg(windows)] unsafe fn msys_tty_on(fd: DWORD) -> bool { use std::{mem, slice}; use winapi::{ ctypes::c_void, shared::minwindef::MAX_PATH, um::{ fileapi::FILE_NAME_INFO, minwinbase::FileNameInfo, processenv::GetStdHandle, winbase::GetFileInformationByHandleEx, }, }; let size = mem::size_of::(); let mut name_info_bytes = vec![0u8; size + MAX_PATH * mem::size_of::()]; let res = GetFileInformationByHandleEx( GetStdHandle(fd), FileNameInfo, &mut *name_info_bytes as *mut _ as *mut c_void, name_info_bytes.len() as u32, ); if res == 0 { return false; } let name_info: &FILE_NAME_INFO = &*(name_info_bytes.as_ptr() as *const FILE_NAME_INFO); let s = slice::from_raw_parts( name_info.FileName.as_ptr(), name_info.FileNameLength as usize / 2, ); let name = String::from_utf16_lossy(s); // This checks whether 'pty' exists in the file name, which indicates that // a pseudo-terminal is attached. To mitigate against false positives // (e.g., an actual file name that contains 'pty'), we also require that // either the strings 'msys-' or 'cygwin-' are in the file name as well.) let is_msys = name.contains("msys-") || name.contains("cygwin-"); let is_pty = name.contains("-pty"); is_msys && is_pty } /// returns true if this is a tty #[cfg(target_arch = "wasm32")] pub fn is(_stream: Stream) -> bool { false } #[cfg(test)] mod tests { use super::{is, Stream}; #[test] #[cfg(windows)] fn is_err() { // appveyor pipes its output assert!(!is(Stream::Stderr)) } #[test] #[cfg(windows)] fn is_out() { // appveyor pipes its output assert!(!is(Stream::Stdout)) } #[test] #[cfg(windows)] fn is_in() { assert!(is(Stream::Stdin)) } #[test] #[cfg(unix)] fn is_err() { assert!(is(Stream::Stderr)) } #[test] #[cfg(unix)] fn is_out() { assert!(is(Stream::Stdout)) } #[test] #[cfg(target_os = "macos")] fn is_in() { // macos on travis seems to pipe its input assert!(is(Stream::Stdin)) } #[test] #[cfg(all(not(target_os = "macos"), unix))] fn is_in() { assert!(is(Stream::Stdin)) } } atty-0.2.13/.cargo_vcs_info.json0000644000000001120000000000000121310ustar00{ "git": { "sha1": "0e6ef0422750c8d24f3e34695758684f48b7a27e" } }