Hi, Rustaceans!
I've been implementing my own bash-history-ish program, and run across this problem: write_all
in a spawned thread does not work.
For example, this code does not work (which means, wl-copy
does not copy the string), though I can see String copied to the clipboard
line in the terminal (Sorry for the Wayland-specific code, but I think the problem is obvious):
use std::io::Write;
fn copy_command(s: &str) -> std::io::Result<()> {
let s = s.to_owned();
println!("Copying: {}", s);
let mut p = std::process::Command::new("wl-copy")
.stdin(std::process::Stdio::piped())
.spawn()?;
let mut stdin = p.stdin.take().expect("Failed to open stdin.");
std::thread::spawn(move || {
stdin.write_all(s.as_bytes()).expect("Failed to write.");
});
Ok(println!("String copied to the clipboard."))
}
fn main() -> std::io::Result<()> {
copy_command("I'm copied - another thread")?;
Ok(())
}
but the following works fine.
use std::io::Write;
fn copy_command(s: &str) -> std::io::Result<()> {
println!("Copying: {}", s);
let mut p = std::process::Command::new("wl-copy")
.stdin(std::process::Stdio::piped())
.spawn()?;
let mut stdin = p.stdin.take().expect("Failed to open stdin.");
stdin.write_all(s.as_bytes()).expect("Failed to write.");
Ok(println!("String copied to the clipboard."))
}
fn main() -> std::io::Result<()> {
copy_command("I'm copied - single thread")?;
Ok(())
}
At the first place I was using thread::spawn()
following this page std::process - Rust, which uses spawn()
, but apparently removing spawn()
and using a single thread make this code work.
So do I misunderstand something important or basic to handle the thread? I'd like to know why this works and that does not, to better understand.
(FYI, in my real code, cargo run
can copy the string, but cargo run -r
cannot, which confused me furthermore.)