summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/examples/dup2_to_replace_stdio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/examples/dup2_to_replace_stdio.rs')
-rw-r--r--vendor/rustix/examples/dup2_to_replace_stdio.rs55
1 files changed, 55 insertions, 0 deletions
diff --git a/vendor/rustix/examples/dup2_to_replace_stdio.rs b/vendor/rustix/examples/dup2_to_replace_stdio.rs
new file mode 100644
index 000000000..cc8565915
--- /dev/null
+++ b/vendor/rustix/examples/dup2_to_replace_stdio.rs
@@ -0,0 +1,55 @@
+//! This is an example of how to use `dup2` to replace the stdin and stdout
+//! file descriptors.
+
+#[cfg(not(windows))]
+fn main() {
+ use rustix::io::{dup2, pipe};
+ 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 (mut stdin, mut 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 `&mut 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, &mut stdin).unwrap();
+ dup2(&writer, &mut 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);
+
+ // Now we can print to "stdout" in the usual way, and it'll go to our pipe.
+ println!("hello, world!");
+
+ // 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)]
+fn main() {
+ unimplemented!()
+}