<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Non-blocking access to stdin, stdout, and stderr.
//!
//! This module provides bindings to the local event loop's TTY interface, using it
//! to offer synchronous but non-blocking versions of stdio. These handles can be
//! inspected for information about terminal dimensions or for related information
//! about the stream or terminal to which it is attached.
//!
//! # Example
//!
//! ```rust
//! # #![allow(unused_must_use)]
//! use std::io;
//!
//! let mut out = io::stdout();
//! out.write(b"Hello, world!");
//! ```

use self::StdSource::*;

use boxed::Box;
use cell::RefCell;
use clone::Clone;
use failure::LOCAL_STDERR;
use fmt;
use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer,
         standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
use kinds::Send;
use libc;
use mem;
use option::Option;
use option::Option::{Some, None};
use ops::{Deref, DerefMut, FnOnce};
use result::Result::{Ok, Err};
use rt;
use slice::SliceExt;
use str::StrPrelude;
use string::String;
use sys::{fs, tty};
use sync::{Arc, Mutex, MutexGuard, Once, ONCE_INIT};
use uint;
use vec::Vec;

// And so begins the tale of acquiring a uv handle to a stdio stream on all
// platforms in all situations. Our story begins by splitting the world into two
// categories, windows and unix. Then one day the creators of unix said let
// there be redirection! And henceforth there was redirection away from the
// console for standard I/O streams.
//
// After this day, the world split into four factions:
//
// 1. Unix with stdout on a terminal.
// 2. Unix with stdout redirected.
// 3. Windows with stdout on a terminal.
// 4. Windows with stdout redirected.
//
// Many years passed, and then one day the nation of libuv decided to unify this
// world. After months of toiling, uv created three ideas: TTY, Pipe, File.
// These three ideas propagated throughout the lands and the four great factions
// decided to settle among them.
//
// The groups of 1, 2, and 3 all worked very hard towards the idea of TTY. Upon
// doing so, they even enhanced themselves further then their Pipe/File
// brethren, becoming the dominant powers.
//
// The group of 4, however, decided to work independently. They abandoned the
// common TTY belief throughout, and even abandoned the fledgling Pipe belief.
// The members of the 4th faction decided to only align themselves with File.
//
// tl;dr; TTY works on everything but when windows stdout is redirected, in that
//        case pipe also doesn't work, but magically file does!
enum StdSource {
    TTY(tty::TTY),
    File(fs::FileDesc),
}

fn src<T, F>(fd: libc::c_int, _readable: bool, f: F) -> T where
    F: FnOnce(StdSource) -> T,
{
    match tty::TTY::new(fd) {
        Ok(tty) => f(TTY(tty)),
        Err(_) => f(File(fs::FileDesc::new(fd, false))),
    }
}

thread_local! {
    static LOCAL_STDOUT: RefCell<Option<Box<Writer + Send>>> = {
        RefCell::new(None)
    }
}

/// A synchronized wrapper around a buffered reader from stdin
#[deriving(Clone)]
pub struct StdinReader {
    inner: Arc<Mutex<BufferedReader<StdReader>>>,
}

/// A guard for exlusive access to `StdinReader`'s internal `BufferedReader`.
pub struct StdinReaderGuard<'a> {
    inner: MutexGuard<'a, BufferedReader<StdReader>>,<commit_msg>rollup merge of #20077: shepmaster/stdin-typo<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Non-blocking access to stdin, stdout, and stderr.
//!
//! This module provides bindings to the local event loop's TTY interface, using it
//! to offer synchronous but non-blocking versions of stdio. These handles can be
//! inspected for information about terminal dimensions or for related information
//! about the stream or terminal to which it is attached.
//!
//! # Example
//!
//! ```rust
//! # #![allow(unused_must_use)]
//! use std::io;
//!
//! let mut out = io::stdout();
//! out.write(b"Hello, world!");
//! ```

use self::StdSource::*;

use boxed::Box;
use cell::RefCell;
use clone::Clone;
use failure::LOCAL_STDERR;
use fmt;
use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer,
         standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
use kinds::Send;
use libc;
use mem;
use option::Option;
use option::Option::{Some, None};
use ops::{Deref, DerefMut, FnOnce};
use result::Result::{Ok, Err};
use rt;
use slice::SliceExt;
use str::StrPrelude;
use string::String;
use sys::{fs, tty};
use sync::{Arc, Mutex, MutexGuard, Once, ONCE_INIT};
use uint;
use vec::Vec;

// And so begins the tale of acquiring a uv handle to a stdio stream on all
// platforms in all situations. Our story begins by splitting the world into two
// categories, windows and unix. Then one day the creators of unix said let
// there be redirection! And henceforth there was redirection away from the
// console for standard I/O streams.
//
// After this day, the world split into four factions:
//
// 1. Unix with stdout on a terminal.
// 2. Unix with stdout redirected.
// 3. Windows with stdout on a terminal.
// 4. Windows with stdout redirected.
//
// Many years passed, and then one day the nation of libuv decided to unify this
// world. After months of toiling, uv created three ideas: TTY, Pipe, File.
// These three ideas propagated throughout the lands and the four great factions
// decided to settle among them.
//
// The groups of 1, 2, and 3 all worked very hard towards the idea of TTY. Upon
// doing so, they even enhanced themselves further then their Pipe/File
// brethren, becoming the dominant powers.
//
// The group of 4, however, decided to work independently. They abandoned the
// common TTY belief throughout, and even abandoned the fledgling Pipe belief.
// The members of the 4th faction decided to only align themselves with File.
//
// tl;dr; TTY works on everything but when windows stdout is redirected, in that
//        case pipe also doesn't work, but magically file does!
enum StdSource {
    TTY(tty::TTY),
    File(fs::FileDesc),
}

fn src<T, F>(fd: libc::c_int, _readable: bool, f: F) -> T where
    F: FnOnce(StdSource) -> T,
{
    match tty::TTY::new(fd) {
        Ok(tty) => f(TTY(tty)),
        Err(_) => f(File(fs::FileDesc::new(fd, false))),
    }
}

thread_local! {
    static LOCAL_STDOUT: RefCell<Option<Box<Writer + Send>>> = {
        RefCell::new(None)
    }
}

/// A synchronized wrapper around a buffered reader from stdin
#[deriving(Clone)]
pub struct StdinReader {
    inner: Arc<Mutex<BufferedReader<StdReader>>>,
}

/// A guard for exclusive access to `StdinReader`'s internal `BufferedReader`.
pub struct StdinReaderGuard<'a> {
    inner: MutexGuard<'a, BufferedReader<StdReader>>,
{'fraction_non_alphanumeric': 0.12332225913621263, 'fraction_numerical': 0.005182724252491695, 'mean_word_length': 3.724419334588826, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5073471', 'n_tokens_mistral': 2340, 'n_tokens_neox': 2246, 'n_words': 933}