General Cleanup to get Cwtch Android Builds Working

- remove smp from qemu as it causes jvm processes to crash
- allow empty lines
This commit is contained in:
Sarah Jamie Lewis 2023-01-19 16:53:45 -08:00
parent 02e46446d5
commit 122eb8b2ac
1 changed files with 43 additions and 27 deletions

View File

@ -1,5 +1,5 @@
use std::fs::{remove_file, File}; use std::fs::{remove_file, File};
use std::io::{BufRead, Read, Write}; use std::io::{BufRead, BufReader, Read, Write};
use std::net::TcpListener; use std::net::TcpListener;
use std::path::Path; use std::path::Path;
use std::process::{exit, Child, Command, Stdio}; use std::process::{exit, Child, Command, Stdio};
@ -15,7 +15,7 @@ pub struct QemuProcess {
} }
/// Pipe streams are blocking, we need separate threads to monitor them without blocking the primary thread. /// Pipe streams are blocking, we need separate threads to monitor them without blocking the primary thread.
fn child_stream_to_vec<R>(mut stream: R) -> Arc<Mutex<Vec<u8>>> fn child_stream_to_vec<R>(stream: R) -> Arc<Mutex<Vec<u8>>>
where where
R: Read + Send + 'static, R: Read + Send + 'static,
{ {
@ -23,24 +23,28 @@ where
let vec = out.clone(); let vec = out.clone();
thread::Builder::new() thread::Builder::new()
.name("child_stream_to_vec".into()) .name("child_stream_to_vec".into())
.spawn(move || loop { .spawn(move || {
let mut buf = [0]; let mut reader = BufReader::new(stream);
match stream.read(&mut buf) {
Err(err) => { loop {
println!("{}] Error reading from stream: {}", line!(), err); let mut buf = vec![0; 8192];
break; match reader.read(&mut buf) {
} Err(err) => {
Ok(got) => { println!("{}] Error reading from stream: {}", line!(), err);
if got == 0 {
break;
} else if got == 1 {
vec.lock().expect("!lock").push(buf[0])
} else {
println!("{}] Unexpected number of bytes: {}", line!(), got);
break; break;
} }
Ok(got) => {
if got == 0 {
break;
} else {
//println!("Waiting for lock");
vec.lock().expect("!lock").extend_from_slice(&buf[0..got]);
//println!("Wrote {} Data", got);
}
}
} }
} }
println!("stream crashed");
}) })
.expect("!thread"); .expect("!thread");
out out
@ -51,10 +55,8 @@ impl QemuProcess {
let mut child = Command::new("qemu-system-x86_64") let mut child = Command::new("qemu-system-x86_64")
.args([ .args([
"-nographic", "-nographic",
"-smp",
"4",
"-m", "-m",
"2048", "4096",
"-net", "-net",
"nic", "nic",
"-net", "-net",
@ -63,11 +65,10 @@ impl QemuProcess {
format!("if=virtio,format=qcow2,file={}", path).as_str(), format!("if=virtio,format=qcow2,file={}", path).as_str(),
"-drive", "-drive",
"if=virtio,format=qcow2,file=vd.img", "if=virtio,format=qcow2,file=vd.img",
"-qmp",
"tcp:localhost:4444,server,wait=off",
]) ])
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::null())
.spawn() .spawn()
.unwrap(); .unwrap();
@ -107,14 +108,28 @@ impl QemuProcess {
} }
pub fn read_until_shell(&mut self, output: bool) -> Vec<String> { pub fn read_until_shell(&mut self, output: bool) -> Vec<String> {
sleep(Duration::from_millis(500)); // wait until attempting to acquire a lock...some programs (especially Java-based) freak out if stdout isn't consumed fast enough...
sleep(Duration::from_millis(2000));
let mut last_length = self.len;
loop { loop {
{ {
let stdout = self.stdout.lock().unwrap(); let stdout = self.stdout.lock().unwrap();
let tbd = String::from_utf8(stdout.as_slice()[self.len..stdout.len()].to_vec()).unwrap(); let tbd = String::from_utf8(stdout.as_slice()[self.len..stdout.len()].to_vec()).unwrap();
let parts: Vec<String> = tbd.split("\n").map(|x| String::from(x)).collect(); let parts: Vec<String> = tbd.split("\n").map(|x| String::from(x)).collect();
let last = &parts[parts.len() - 1]; let last = &parts[parts.len() - 1];
if last.contains("root@debian:") && last.ends_with("# ") {
let current_length = stdout.len();
if current_length > last_length {
if output {
println!("{}", tbd);
std::io::stdout().flush().expect("could not flush output");
}
}
// Update length
last_length = current_length;
if last.contains("root@debian:") {
let mut cleaned_lines = vec![]; let mut cleaned_lines = vec![];
println!(". \x1b[1;32mOK\x1b[0m"); println!(". \x1b[1;32mOK\x1b[0m");
// skip the last element (which is the shell prompt) // skip the last element (which is the shell prompt)
@ -139,9 +154,6 @@ impl QemuProcess {
} }
self.len = stdout.len(); self.len = stdout.len();
return cleaned_lines; return cleaned_lines;
} else {
print!(".");
std::io::stdout().flush().expect("could not flush output")
} }
} }
sleep(Duration::from_millis(2000)); sleep(Duration::from_millis(2000));
@ -151,7 +163,7 @@ impl QemuProcess {
pub fn execute_command(&mut self, cmd: &str) { pub fn execute_command(&mut self, cmd: &str) {
let child_stdin = self.child.stdin.as_mut().unwrap(); let child_stdin = self.child.stdin.as_mut().unwrap();
child_stdin child_stdin
.write_all(format!("{}\n", cmd).as_ref()) .write_all(format!("{}\r\n", cmd).as_ref())
.unwrap(); .unwrap();
child_stdin.flush().expect("could not write"); child_stdin.flush().expect("could not write");
print!("{} ", cmd); print!("{} ", cmd);
@ -230,6 +242,10 @@ fn main() {
let mut command = line.clone(); let mut command = line.clone();
let mut output = false; let mut output = false;
if line.trim().is_empty() {
continue;
}
if line.trim().starts_with("#") { if line.trim().starts_with("#") {
// comment - skip // comment - skip
continue; continue;