drop stdin on childproc_await to prevent deadlocks, add flush() call after childproc_write_*

This commit is contained in:
Mark 2024-02-17 12:06:04 +01:00
parent 6fdfba82a0
commit d124bff77f

View File

@ -108,7 +108,7 @@ impl Config {
.spawn() .spawn()
{ {
Ok(mut child) => { Ok(mut child) => {
let a = child.stdin.take().unwrap(); let a = Some(child.stdin.take().unwrap());
let b = BufReader::new(child.stdout.take().unwrap()); let b = BufReader::new(child.stdout.take().unwrap());
let c = BufReader::new(child.stderr.take().unwrap()); let c = BufReader::new(child.stderr.take().unwrap());
Data::new(ChildProcess(Arc::new(Mutex::new((child, a, b, c))))) Data::new(ChildProcess(Arc::new(Mutex::new((child, a, b, c)))))
@ -160,13 +160,14 @@ impl Config {
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
])) ]))
} else { } else {
return Err(format!("childproc_exited called on non-ChildProcess type {a}").into()); return Err(format!("childproc_await called on non-ChildProcess type {a}").into());
} }
}), }),
run: Arc::new(|a, _i| { run: Arc::new(|a, _i| {
let a = a.get(); let a = a.get();
let child = a.as_any().downcast_ref::<ChildProcess>().unwrap(); let child = a.as_any().downcast_ref::<ChildProcess>().unwrap();
let mut child = child.0.lock().unwrap(); let mut child = child.0.lock().unwrap();
drop(child.1.take());
match child.0.wait() { match child.0.wait() {
Ok(s) => if let Some(s) = s.code() { Ok(s) => if let Some(s) = s.code() {
Data::new(data::int::Int(s as _)) Data::new(data::int::Int(s as _))
@ -199,7 +200,7 @@ impl Config {
let child = child.as_any().downcast_ref::<ChildProcess>().unwrap(); let child = child.as_any().downcast_ref::<ChildProcess>().unwrap();
let mut child = child.0.lock().unwrap(); let mut child = child.0.lock().unwrap();
let buf = bytes.iterable().unwrap().map(|v| v.get().as_any().downcast_ref::<data::int::Int>().unwrap().0.max(0).min(255) as u8).collect::<Vec<_>>(); let buf = bytes.iterable().unwrap().map(|v| v.get().as_any().downcast_ref::<data::int::Int>().unwrap().0.max(0).min(255) as u8).collect::<Vec<_>>();
if child.1.write_all(&buf).is_ok() { if child.1.as_mut().is_some_and(|v| v.write_all(&buf).is_ok() && v.flush().is_ok()) {
Data::new(data::bool::Bool(true)) Data::new(data::bool::Bool(true))
} else { } else {
Data::new(data::bool::Bool(false)) Data::new(data::bool::Bool(false))
@ -228,7 +229,7 @@ impl Config {
let child = child.as_any().downcast_ref::<ChildProcess>().unwrap(); let child = child.as_any().downcast_ref::<ChildProcess>().unwrap();
let mut child = child.0.lock().unwrap(); let mut child = child.0.lock().unwrap();
let buf = string.as_any().downcast_ref::<data::string::String>().unwrap().0.as_bytes(); let buf = string.as_any().downcast_ref::<data::string::String>().unwrap().0.as_bytes();
if child.1.write_all(buf).is_ok() { if child.1.as_mut().is_some_and(|v| v.write_all(buf).is_ok() && v.flush().is_ok()) {
Data::new(data::bool::Bool(true)) Data::new(data::bool::Bool(true))
} else { } else {
Data::new(data::bool::Bool(false)) Data::new(data::bool::Bool(false))
@ -361,7 +362,7 @@ pub struct ChildProcess(
Arc< Arc<
Mutex<( Mutex<(
std::process::Child, std::process::Child,
ChildStdin, Option<ChildStdin>,
BufReader<ChildStdout>, BufReader<ChildStdout>,
BufReader<ChildStderr>, BufReader<ChildStderr>,
)>, )>,