in smt2proxy/src/main.rs [130:208]
fn process_events(
receiver: std::sync::mpsc::Receiver<Event>,
z3_args: Vec<String>,
mut processor: smt2proxy::CommandProcessor,
) {
if let Some(logger) = processor.logger() {
let mut f = logger.lock().unwrap();
writeln!(
f,
"; z3 {}",
z3_args
.iter()
.map(|x| format!("\"{}\"", x))
.collect::<Vec<_>>()
.join(" ")
)
.unwrap();
}
let mut child = std::process::Command::new("z3")
.args(&z3_args)
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap();
let handler_stdout = spawn_child_stream_logger(
processor.logger().clone(),
child.stdout.take().expect("Failed to open child stdout"),
/* repeat */ true,
"Failed to read child stdout",
);
let handler_stderr = spawn_child_stream_logger(
processor.logger().clone(),
child.stderr.take().expect("Failed to open child stderr"),
/* repeat */ false,
"Failed to read child stderr",
);
{
let mut child_stdin = child.stdin.take().expect("Failed to open child stdin");
while let Ok(event) = receiver.recv() {
match event {
Event::Query(value) => match *value {
Ok(in_command) => {
let out_commands = processor.process(in_command);
for command in out_commands {
writeln!(child_stdin, "{}", command)
.expect("Failed to write to child stdin");
}
}
Err(error) => {
if let Some(logger) = processor.logger() {
let mut f = logger.lock().unwrap();
writeln!(f, "; {}", error).expect("Failed to write to log file");
}
break;
}
},
Event::Done => {
break;
}
}
}
let out_commands = processor.stop();
for command in out_commands {
writeln!(child_stdin, "{}", command).expect("Failed to write to child stdin");
}
}
// child_stdin is now closed.
// Wait for z3 to read EOF and terminate normally.
child.wait().unwrap();
// Wait for the child stream loggers to read EOF and terminate.
handler_stdout.join().unwrap();
handler_stderr.join().unwrap();
}