Enable Reading From Stdin In Child Threads
So, at the moment, there are two key areas within Ion where a fork occurs and we are unable to read from stdin in the child without causing some major issues in the parent. Process expansions, and background commands. It's probably a simple fix that I've overlooked. Example code from process expansions:
let (mut out_read, out_write) = match sys::pipe2(sys::O_CLOEXEC) {
Ok(fds) => unsafe { (File::from_raw_fd(fds.0), File::from_raw_fd(fds.1)) },
Err(why) => {
eprintln!("ion: unable to create pipe: {}", why);
return None;
}
};
match unsafe { sys::fork() } {
Ok(0) => {
// TODO: Figure out how to properly enable stdin in the child.
// Without this line, the parent will hang. Can test with:
// echo $(read x)
sys::close_stdin();
// Redirect stdout in the child to the write end of the pipe.
// Also close the read end of the pipe because we don't need it.
let _ = sys::dup2(out_write.as_raw_fd(), sys::STDOUT_FILENO);
drop(out_write);
drop(out_read);
// Now obtain ownership of the child's shell through a mutable pointer,
// and then use that shell to execute the command.
let shell: &mut Shell = unsafe { &mut *self.pointer };
shell.on_command(command);
// Reap the child, enabling the parent to get EOF from the read end of the pipe.
exit(0);
}
Ok(_pid) => {
// Drop the write end of the pipe, because the parent will not use it.
drop(out_write);
// Read from the read end of the pipe into a String.
let mut output = String::new();
let _ = out_read.read_to_string(&mut output);
Some(output)
}
Err(why) => {
eprintln!("ion: fork error: {}", why);
None
}
}