Drop child read handle as soon as possible

This commit is contained in:
Austen Adler 2022-12-18 11:16:43 -05:00
parent 82239eeb8e
commit 853770613e
3 changed files with 30 additions and 20 deletions

View File

@ -15,11 +15,13 @@ use std::{
pub type CommandRequest = (Arc<RwLock<CommandOptions>>, Arc<String>);
use crate::App;
#[derive(Debug)]
pub enum CommandCompleted {
Success(CommandResult),
Failure(Vec<u8>),
}
#[derive(Debug)]
pub struct CommandResult {
pub status_success: bool,
pub stdout: Vec<u8>,
@ -84,29 +86,35 @@ pub fn command_event_loop(
// }
fn run_inner(command_request: CommandRequest) -> Result<CommandResult> {
let request = command_request.0.read();
// Spawn the child
let mut child = {
let request = command_request.0.read();
let mut command = Command::new(&request.command);
command
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.args(&request.hidden_options);
let mut command = Command::new(&request.command);
command
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.args(&request.hidden_options);
if request.wordsplit {
match shellwords::split(&request.cmdline) {
Ok(a) => {
command.args(a);
}
Err(e) => {
bail!("Argument error: {e:?}");
if request.wordsplit {
match shellwords::split(&request.cmdline) {
Ok(a) => {
command.args(a);
}
Err(e) => {
bail!("Argument error: {e:?}");
}
}
} else {
// TODO: Avoid cloning here
command.arg(&request.cmdline);
}
} else {
// TODO: Avoid cloning here
command.arg(&request.cmdline);
}
let mut child = command.spawn()?;
std::mem::drop(request);
command.spawn()
}?;
let mut stdin = child.stdin.take().context("Could not take stdin")?;
let text_orig_clone = command_request.1.clone();

View File

@ -3,6 +3,7 @@ use anyhow::bail;
use anyhow::Result;
use crossbeam::channel::Sender;
#[derive(Debug)]
pub enum EventMessage {
CommandCompleted(CommandCompleted),
CrosstermEvent(crossterm::event::Event),

View File

@ -273,18 +273,19 @@ fn init_message_passing() -> (Receiver<EventMessage>, Sender<CommandRequest>) {
let _result = command::command_event_loop(command_request_rx, command_message_tx);
});
// Drop the remaining transmitter
std::mem::drop(message_tx);
(message_rx, command_request_tx)
}
fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: App) -> Result<Option<(String, Vec<u8>)>> {
// When starting the app, ensure the command runs at least once
{
let mut command_options = app.command_options.write();
if !command_options.cmdline.is_empty() {
app.run_command()?;
// command_request_tx.send((app.command_options.clone(), app.text_orig.clone()))?;
}
if command_options.cmdline_position == 0 {