Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/arch/src/serial/sys/windows.rs
5394 views
1
// Copyright 2022 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
#![allow(dead_code)]
6
7
use std::io::Read;
8
use std::sync::Arc;
9
use std::thread;
10
use std::time::Duration;
11
12
use base::RawDescriptor;
13
use base::Result;
14
use devices::serial_device::SerialParameters;
15
use devices::serial_device::SerialType;
16
use devices::BusDevice;
17
use devices::Serial;
18
use jail::FakeMinijailStub as Minijail;
19
use sync::Mutex;
20
21
use crate::DeviceRegistrationError;
22
23
/// A type for queueing input bytes to a serial device that abstracts if the device is local or part
24
/// of a sandboxed device process.
25
/// TODO(b/160806152) rizhang: Move to different file for readability.
26
pub enum SerialInput {
27
#[doc(hidden)]
28
Local(Arc<Mutex<Serial>>),
29
}
30
31
impl SerialInput {
32
/// Creates a `SerialInput` that trivially forwards queued bytes to the device in the local
33
/// process.
34
pub fn new_local(serial: Arc<Mutex<Serial>>) -> SerialInput {
35
SerialInput::Local(serial)
36
}
37
38
/// Just like `Serial::queue_input_bytes`, but abstracted over local and sandboxed serial
39
/// devices.
40
pub fn queue_input_bytes(&self, bytes: &[u8]) -> Result<()> {
41
match self {
42
SerialInput::Local(device) => device.lock().queue_input_bytes(bytes),
43
}
44
}
45
}
46
47
pub fn add_serial_device(
48
com: Serial,
49
serial_params: &SerialParameters,
50
serial_jail: Option<Minijail>,
51
_preserved_descriptors: Vec<RawDescriptor>,
52
) -> std::result::Result<Arc<Mutex<dyn BusDevice>>, DeviceRegistrationError> {
53
assert!(serial_jail.is_none());
54
55
let com = Arc::new(Mutex::new(com));
56
57
if !serial_params.stdin {
58
if let SerialType::SystemSerialType = serial_params.type_ {
59
let mut in_pipe_result = com
60
.lock()
61
.system_params
62
.in_stream
63
.as_ref()
64
.unwrap()
65
.try_clone();
66
let com = com.clone();
67
thread::spawn(move || {
68
let serial_input = SerialInput::new_local(com);
69
let in_pipe = in_pipe_result.as_mut().unwrap();
70
71
let mut buffer: [u8; 255] = [0; 255];
72
loop {
73
// Safe because we are reading bytes.
74
let bytes = in_pipe.read(&mut buffer).unwrap_or(0);
75
if bytes > 0 {
76
serial_input.queue_input_bytes(&buffer[0..bytes]).unwrap();
77
}
78
// We can't issue blocking reads here and overlapped I/O is
79
// incompatible with the call site where writes to this pipe are being
80
// made, so instead we issue a small wait to prevent us from hogging
81
// the CPU. This 20ms delay while typing doesn't seem to be noticeable.
82
thread::sleep(Duration::from_millis(20));
83
}
84
});
85
}
86
}
87
88
Ok(com)
89
}
90
91