mirror of
https://github.com/openharmony/third_party_rust_rustix.git
synced 2026-07-19 23:03:36 -04:00
Add comments to dup2_to_replace_stdio.
And while here, simplify the code to use `println!` to print "hello world", which we can do now that it's no longer running within the test harness process.
This commit is contained in:
@@ -3,35 +3,49 @@
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn main() {
|
||||
use io_lifetimes::AsFilelike;
|
||||
use rustix::io::{dup2, pipe};
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::mem::forget;
|
||||
|
||||
// Create some new file descriptors that we'll use to replace stdio's file
|
||||
// descriptors with.
|
||||
let (reader, writer) = pipe().unwrap();
|
||||
|
||||
// Acquire `OwnedFd` instances for stdin and stdout. These APIs are `unsafe`
|
||||
// because in general, with low-level APIs like this, libraries can't assume
|
||||
// that stdin and stdout will be open or safe to use. It's ok here, because
|
||||
// we're directly inside `main`, so we know that stdin and stdout haven't
|
||||
// been closed and aren't being used for other purposes.
|
||||
let (stdin, stdout) = unsafe { (rustix::io::take_stdin(), rustix::io::take_stdout()) };
|
||||
|
||||
// Use `dup2` to copy our new file descriptors over the stdio file descriptors.
|
||||
//
|
||||
// These take their second argument as an `&OwnedFd` rather than the usual
|
||||
// `impl AsFd` because they conceptually do a `close` on the original file
|
||||
// descriptor, which one shouldn't be able to do with just a `BorrowedFd`.
|
||||
dup2(&reader, &stdin).unwrap();
|
||||
dup2(&writer, &stdout).unwrap();
|
||||
|
||||
// Then, forget the stdio `OwnedFd`s, because actually dropping them would
|
||||
// close them. Here, we want stdin and stdout to remain open for the rest
|
||||
// of the program.
|
||||
forget(stdin);
|
||||
forget(stdout);
|
||||
|
||||
// We can also drop the original file descriptors now, since `dup2` creates
|
||||
// new file descriptors with independent lifetimes.
|
||||
drop(reader);
|
||||
drop(writer);
|
||||
|
||||
// Don't use `std::io::stdout()` because in tests it's captured.
|
||||
unsafe {
|
||||
writeln!(
|
||||
rustix::io::stdout().as_filelike_view::<std::fs::File>(),
|
||||
"hello, world!"
|
||||
)
|
||||
.unwrap();
|
||||
// Now we can print to "stdout" in the usual way, and it'll go to our pipe.
|
||||
println!("hello, world!");
|
||||
|
||||
let mut s = String::new();
|
||||
BufReader::new(&*rustix::io::stdin().as_filelike_view::<std::fs::File>())
|
||||
.read_line(&mut s)
|
||||
.unwrap();
|
||||
assert_eq!(s, "hello, world!\n");
|
||||
}
|
||||
// And we can read from stdin, and it'll read from our pipe. It's a little
|
||||
// silly that we connected our stdout to our own stdin, but it's just an
|
||||
// example :-).
|
||||
let mut s = String::new();
|
||||
BufReader::new(std::io::stdin()).read_line(&mut s).unwrap();
|
||||
assert_eq!(s, "hello, world!\n");
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
||||
Reference in New Issue
Block a user