Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/sys/windows/serial_device.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
use std::io;
6
7
use base::named_pipes;
8
use base::named_pipes::BlockingMode;
9
use base::named_pipes::FramingMode;
10
use base::AsRawDescriptor;
11
pub use base::Console as ConsoleInput;
12
use base::Event;
13
use base::FileSync;
14
use base::RawDescriptor;
15
use hypervisor::ProtectionType;
16
17
use crate::serial_device::Error;
18
use crate::serial_device::SerialInput;
19
use crate::serial_device::SerialOptions;
20
use crate::serial_device::SerialParameters;
21
22
pub const SYSTEM_SERIAL_TYPE_NAME: &str = "NamedPipe";
23
24
/// Abstraction over serial-like devices that can be created given an event and optional input and
25
/// output streams.
26
pub trait SerialDevice {
27
fn new(
28
protection_type: ProtectionType,
29
interrupt_evt: Event,
30
input: Option<Box<dyn SerialInput>>,
31
output: Option<Box<dyn io::Write + Send>>,
32
sync: Option<Box<dyn FileSync + Send>>,
33
options: SerialOptions,
34
keep_rds: Vec<RawDescriptor>,
35
) -> Self;
36
fn new_with_pipe(
37
protection_type: ProtectionType,
38
interrupt_evt: Event,
39
pipe_in: named_pipes::PipeConnection,
40
pipe_out: named_pipes::PipeConnection,
41
options: SerialOptions,
42
keep_rds: Vec<RawDescriptor>,
43
) -> Self;
44
}
45
46
pub(crate) fn create_system_type_serial_device<T: SerialDevice>(
47
param: &SerialParameters,
48
protection_type: ProtectionType,
49
evt: Event,
50
_input: Option<Box<dyn SerialInput>>,
51
keep_rds: &mut Vec<RawDescriptor>,
52
) -> std::result::Result<T, Error> {
53
match &param.path {
54
None => Err(Error::PathRequired),
55
Some(path) => {
56
// Note that when this pipe is not connected, the serial device will
57
// discard output. If the pipe's buffer is allowed to fill, writes
58
// will block, which will stall the output queue. This generally
59
// points to a bug in the named pipe consumer, and if desired we
60
// could address it in CrosVM by adding a write timeout.
61
let pipe_in = named_pipes::create_server_pipe(
62
path.to_str().unwrap(),
63
&FramingMode::Byte,
64
&BlockingMode::Wait,
65
/* timeout= */ 0,
66
named_pipes::DEFAULT_BUFFER_SIZE,
67
/* overlapped= */ true,
68
)
69
.map_err(Error::SystemTypeError)?;
70
71
let pipe_out = pipe_in.try_clone().map_err(Error::SystemTypeError)?;
72
73
keep_rds.push(pipe_in.as_raw_descriptor());
74
keep_rds.push(pipe_out.as_raw_descriptor());
75
76
Ok(T::new_with_pipe(
77
protection_type,
78
evt,
79
pipe_in,
80
pipe_out,
81
Default::default(),
82
keep_rds.to_vec(),
83
))
84
}
85
}
86
}
87
88