Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/e2e_tests/guest_under_test/rootfs/delegate/src/main.rs
5394 views
1
// Copyright 2020 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
/// Very crude interactive console to allow the test host to run shell commands
6
/// in the guest and receive the output.
7
mod wire_format;
8
9
use std::fs::File;
10
use std::io;
11
use std::io::prelude::*;
12
#[cfg(any(target_os = "android", target_os = "linux"))]
13
use std::os::unix::process::ExitStatusExt;
14
use std::path::Path;
15
use std::process::Command;
16
use std::str;
17
18
use serde_json::Deserializer;
19
20
use crate::wire_format::DelegateMessage;
21
use crate::wire_format::GuestToHostMessage;
22
use crate::wire_format::HostToGuestMessage;
23
use crate::wire_format::ProgramExit;
24
25
/// Device file to read from and write to.
26
const CONSOLE_FILE: &str = "/dev/ttyS1";
27
28
fn listen(
29
input: &mut dyn Iterator<Item = Result<DelegateMessage, serde_json::Error>>,
30
mut output: Box<dyn io::Write>,
31
) -> io::Result<()> {
32
output.write_all(
33
serde_json::to_string_pretty(&DelegateMessage::GuestToHost(GuestToHostMessage::Ready))
34
.unwrap()
35
.as_bytes(),
36
)?;
37
loop {
38
if let Some(command) = input.next() {
39
match command?.assume_host_to_guest() {
40
HostToGuestMessage::Exit => {
41
break;
42
}
43
HostToGuestMessage::RunCommand {
44
command: command_string,
45
} => {
46
println!("-> {}", &command_string);
47
let result = Command::new("/bin/sh")
48
.args(["-c", &command_string])
49
.output()
50
.unwrap();
51
let command_result = GuestToHostMessage::ProgramExit(ProgramExit {
52
stdout: String::from_utf8_lossy(&result.stdout).into_owned(),
53
stderr: String::from_utf8_lossy(&result.stderr).into_owned(),
54
exit_status: match result.status.code() {
55
Some(code) => wire_format::ExitStatus::Code(code),
56
#[cfg(any(target_os = "android", target_os = "linux"))]
57
None => match result.status.signal() {
58
Some(signal) => wire_format::ExitStatus::Signal(signal),
59
None => wire_format::ExitStatus::None,
60
},
61
#[cfg(not(unix))]
62
_ => wire_format::ExitStatus::None,
63
},
64
});
65
println!(
66
"<- {}",
67
serde_json::to_string_pretty(&command_result).unwrap()
68
);
69
output.write_all(
70
serde_json::to_string_pretty(&DelegateMessage::GuestToHost(command_result))
71
.unwrap()
72
.as_bytes(),
73
)?;
74
}
75
}
76
}
77
}
78
Ok(())
79
}
80
81
fn main() {
82
let path = Path::new(CONSOLE_FILE);
83
84
let mut command_stream =
85
Deserializer::from_reader(File::open(path).unwrap()).into_iter::<DelegateMessage>();
86
87
listen(&mut command_stream, Box::new(File::create(path).unwrap())).unwrap();
88
}
89
90