• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 use std::thread;
7 use std::time::Duration;
8 
9 use base::named_pipes;
10 use base::Event;
11 use base::FileSync;
12 use base::RawDescriptor;
13 
14 use crate::serial_device::SerialInput;
15 use crate::virtio::console::Console;
16 use crate::virtio::console::ConsoleInput;
17 use crate::virtio::ProtectionType;
18 use crate::SerialDevice;
19 
20 impl SerialDevice for Console {
new( protection_type: ProtectionType, _event: Event, _input: Option<Box<dyn SerialInput>>, out: Option<Box<dyn io::Write + Send>>, _sync: Option<Box<dyn FileSync + Send>>, _out_timestamp: bool, keep_rds: Vec<RawDescriptor>, ) -> Console21     fn new(
22         protection_type: ProtectionType,
23         _event: Event,
24         _input: Option<Box<dyn SerialInput>>,
25         out: Option<Box<dyn io::Write + Send>>,
26         // TODO(b/171331752): connect filesync functionality.
27         _sync: Option<Box<dyn FileSync + Send>>,
28         _out_timestamp: bool,
29         keep_rds: Vec<RawDescriptor>,
30     ) -> Console {
31         Console::new(protection_type, None, out, keep_rds)
32     }
33 
34     /// Constructs a console with named pipe as input/output connections.
new_with_pipe( protection_type: ProtectionType, _interrupt_evt: Event, pipe_in: named_pipes::PipeConnection, pipe_out: named_pipes::PipeConnection, keep_rds: Vec<RawDescriptor>, ) -> Console35     fn new_with_pipe(
36         protection_type: ProtectionType,
37         _interrupt_evt: Event,
38         pipe_in: named_pipes::PipeConnection,
39         pipe_out: named_pipes::PipeConnection,
40         keep_rds: Vec<RawDescriptor>,
41     ) -> Console {
42         Console::new(
43             protection_type,
44             Some(ConsoleInput::FromRead(Box::new(pipe_in))),
45             Some(Box::new(pipe_out)),
46             keep_rds,
47         )
48     }
49 }
50 
51 /// Platform-specific function to add a delay for reading rx.
52 ///
53 /// We can't issue blocking reads here and overlapped I/O is
54 /// incompatible with the call site where writes to this pipe are being
55 /// made, so instead we issue a small wait to prevent us from hogging
56 /// the CPU. This 20ms delay while typing doesn't seem to be noticeable.
read_delay_if_needed()57 pub(in crate::virtio::console) fn read_delay_if_needed() {
58     thread::sleep(Duration::from_millis(20));
59 }
60 
is_a_fatal_input_error(e: &io::Error) -> bool61 pub(in crate::virtio::console) fn is_a_fatal_input_error(e: &io::Error) -> bool {
62     !matches!(
63         e.kind(),
64         // Being interrupted is not an error.
65         io::ErrorKind::Interrupted |
66         // Ignore two kinds of errors on Windows.
67         //   - ErrorKind::Other when reading a named pipe before a client connects.
68         //   - ErrorKind::WouldBlock when reading a named pipe (we don't use non-blocking I/O).
69         io::ErrorKind::Other | io::ErrorKind::WouldBlock
70     )
71     // Everything else is a fatal input error.
72 }
73