I am writing a small application that spawns a child process and receives the response through the pipe created. I am getting the data back but I am seeing a fatal runtime error because of double free of fd. I am using "interprocess" crate for this. I am seeing similar issue with "os_pipe" crate too. Below is the code snippet. After exiting the function recv_till_end, rx_pipe is dropped and as part of that I see the error. Please help. Thanks
Error:
fatal runtime error: IO Safety violation: owned file descriptor already closed
Code Snippet:
use interprocess::unnamed_pipe::pipe;
use interprocess::unnamed_pipe::{Recver, Sender};
use std::io;
use std::io::{Read, Write};
use std::os::fd::{AsRawFd, RawFd};
use std::io::Error;
use std::io::ErrorKind;
use std::os::fd::FromRawFd;
use std::process::Stdio;
pub struct Pipe {
txer: Sender,
rxer: Recver,
}
impl Pipe {
pub fn new() -> Self {
let (txer, rxer) = pipe().unwrap();
let p = Pipe {
txer: txer,
rxer: rxer,
};
println!(
"Pipe::new() - txer: {:?}, rxer: {:?}",
p.txer.as_raw_fd(),
p.rxer.as_raw_fd()
);
p
}
pub fn tx_raw_fd(&self) -> Stdio {
unsafe { Stdio::from_raw_fd(self.txer.as_raw_fd()) }
}
pub fn rx_raw_fd(&self) -> Stdio {
unsafe { Stdio::from_raw_fd(self.rxer).as_raw_fd()) }
}
}
Usage:
async fn recv_till_end(&mut self) -> Result<(), Error> {
let mut rx_pipe = Pipe::new();
let mut cmd = Command::new(self.params.exe_path.as_ref().unwrap());
cmd.stdout(rx_pipe.tx_raw_fd());
let mut child = cmd.spawn()?;
drop(cmd); // Release the Command instance since we have the Child
let data = rx_pipe.rx_to_end(1024)?;
println!("recv_till_end data len: {}", data.len());
child.wait()?;
Ok(())
}