1//! This is an example of how to use `dup2` to replace the stdin and stdout 2//! file descriptors. 3 4#[cfg(not(windows))] 5fn main() { 6 use rustix::io::{dup2, pipe}; 7 use std::io::{BufRead, BufReader}; 8 use std::mem::forget; 9 10 // Create some new file descriptors that we'll use to replace stdio's file 11 // descriptors with. 12 let (reader, writer) = pipe().unwrap(); 13 14 // Acquire `OwnedFd` instances for stdin and stdout. These APIs are `unsafe` 15 // because in general, with low-level APIs like this, libraries can't assume 16 // that stdin and stdout will be open or safe to use. It's ok here, because 17 // we're directly inside `main`, so we know that stdin and stdout haven't 18 // been closed and aren't being used for other purposes. 19 let (mut stdin, mut stdout) = unsafe { (rustix::io::take_stdin(), rustix::io::take_stdout()) }; 20 21 // Use `dup2` to copy our new file descriptors over the stdio file descriptors. 22 // 23 // These take their second argument as an `&mut OwnedFd` rather than the 24 // usual `impl AsFd` because they conceptually do a `close` on the original 25 // file descriptor, which one shouldn't be able to do with just a 26 // `BorrowedFd`. 27 dup2(&reader, &mut stdin).unwrap(); 28 dup2(&writer, &mut stdout).unwrap(); 29 30 // Then, forget the stdio `OwnedFd`s, because actually dropping them would 31 // close them. Here, we want stdin and stdout to remain open for the rest 32 // of the program. 33 forget(stdin); 34 forget(stdout); 35 36 // We can also drop the original file descriptors now, since `dup2` creates 37 // new file descriptors with independent lifetimes. 38 drop(reader); 39 drop(writer); 40 41 // Now we can print to "stdout" in the usual way, and it'll go to our pipe. 42 println!("hello, world!"); 43 44 // And we can read from stdin, and it'll read from our pipe. It's a little 45 // silly that we connected our stdout to our own stdin, but it's just an 46 // example :-). 47 let mut s = String::new(); 48 BufReader::new(std::io::stdin()).read_line(&mut s).unwrap(); 49 assert_eq!(s, "hello, world!\n"); 50} 51 52#[cfg(windows)] 53fn main() { 54 unimplemented!() 55} 56