diff options
| author | bors <bors@rust-lang.org> | 2016-01-26 13:26:08 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-01-26 13:26:08 +0000 |
| commit | 5d6e8fcedac1184a28031ee0cf63e2d862e4536f (patch) | |
| tree | 73ca828212a1d995b4cab760b207964f9c6e8231 /src/test | |
| parent | 43c1a173a874f5513db58b2f5321489a00087484 (diff) | |
| parent | b6faae11f46b18221555759d3e6fad12cbd0ee97 (diff) | |
| download | rust-5d6e8fcedac1184a28031ee0cf63e2d862e4536f.tar.gz rust-5d6e8fcedac1184a28031ee0cf63e2d862e4536f.zip | |
Auto merge of #31214 - Manishearth:rollup, r=Manishearth
- Successful merges: #31172, #31177, #31211 - Failed merges:
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/run-fail-fulldeps/qquote.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/no-stdio.rs | 124 |
2 files changed, 125 insertions, 1 deletions
diff --git a/src/test/run-fail-fulldeps/qquote.rs b/src/test/run-fail-fulldeps/qquote.rs index d42a777a019..41a6fd05c37 100644 --- a/src/test/run-fail-fulldeps/qquote.rs +++ b/src/test/run-fail-fulldeps/qquote.rs @@ -10,7 +10,7 @@ // ignore-cross-compile -// error-pattern:expected identifier, found keyword `let` +// error-pattern:expected expression, found statement (`let`) #![feature(quote, rustc_private)] diff --git a/src/test/run-pass/no-stdio.rs b/src/test/run-pass/no-stdio.rs new file mode 100644 index 00000000000..3658b6a508a --- /dev/null +++ b/src/test/run-pass/no-stdio.rs @@ -0,0 +1,124 @@ +// Copyright 2016 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. + +#![feature(libc)] + +extern crate libc; + +use std::process::{Command, Stdio}; +use std::env; +use std::io::{self, Read, Write}; + +#[cfg(unix)] +unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R { + let doit = |a| { + let r = libc::dup(a); + assert!(r >= 0); + return r + }; + let a = doit(0); + let b = doit(1); + let c = doit(2); + + assert!(libc::close(0) >= 0); + assert!(libc::close(1) >= 0); + assert!(libc::close(2) >= 0); + + let r = f(); + + assert!(libc::dup2(a, 0) >= 0); + assert!(libc::dup2(b, 1) >= 0); + assert!(libc::dup2(c, 2) >= 0); + + return r +} + +#[cfg(windows)] +unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R { + type DWORD = u32; + type HANDLE = *mut u8; + type BOOL = i32; + + const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD; + const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; + const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; + const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE; + + extern "system" { + fn GetStdHandle(which: DWORD) -> HANDLE; + fn SetStdHandle(which: DWORD, handle: HANDLE) -> BOOL; + } + + let doit = |id| { + let handle = GetStdHandle(id); + assert!(handle != INVALID_HANDLE_VALUE); + assert!(SetStdHandle(id, INVALID_HANDLE_VALUE) != 0); + return handle + }; + + let a = doit(STD_INPUT_HANDLE); + let b = doit(STD_OUTPUT_HANDLE); + let c = doit(STD_ERROR_HANDLE); + + let r = f(); + + let doit = |id, handle| { + assert!(SetStdHandle(id, handle) != 0); + }; + doit(STD_INPUT_HANDLE, a); + doit(STD_OUTPUT_HANDLE, b); + doit(STD_ERROR_HANDLE, c); + + return r +} + +fn main() { + if env::args().len() > 1 { + println!("test"); + assert!(io::stdout().write(b"test\n").is_ok()); + assert!(io::stderr().write(b"test\n").is_ok()); + assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0); + return + } + + // First, make sure reads/writes without stdio work if stdio itself is + // missing. + let (a, b, c) = unsafe { + without_stdio(|| { + let a = io::stdout().write(b"test\n"); + let b = io::stderr().write(b"test\n"); + let c = io::stdin().read(&mut [0; 10]); + + (a, b, c) + }) + }; + + assert_eq!(a.unwrap(), 5); + assert_eq!(b.unwrap(), 5); + assert_eq!(c.unwrap(), 0); + + // Second, spawn a child and do some work with "null" descriptors to make + // sure it's ok + let me = env::current_exe().unwrap(); + let status = Command::new(&me) + .arg("next") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status().unwrap(); + assert!(status.success(), "{:?} isn't a success", status); + + // Finally, close everything then spawn a child to make sure everything is + // *still* ok. + let status = unsafe { + without_stdio(|| Command::new(&me).arg("next").status()) + }.unwrap(); + assert!(status.success(), "{:?} isn't a success", status); +} |
