// Copyright (c) 2020 Huawei Technologies Co.,Ltd. All rights reserved. // // StratoVirt is licensed under Mulan PSL v2. // You can use this software according to the terms and conditions of the Mulan // PSL v2. // You may obtain a copy of Mulan PSL v2 at: // http://license.coscl.org.cn/MulanPSL2 // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. // See the Mulan PSL v2 for more details. pub mod aio; pub mod arg_parser; pub mod bitmap; pub mod byte_code; pub mod checksum; pub mod clock; pub mod daemonize; #[cfg(target_arch = "aarch64")] pub mod device_tree; pub mod edid; pub mod error; pub mod file; pub mod leak_bucket; pub mod link_list; pub mod logger; pub mod loop_context; pub mod num_ops; pub mod offsetof; #[cfg(feature = "pixman")] pub mod pixman; pub mod reader; pub mod seccomp; pub mod syscall; pub mod tap; pub mod test_helper; pub mod time; pub mod trace; pub mod unix; #[cfg(feature = "usb_camera_v4l2")] pub mod v4l2; pub use anyhow::Result; pub use error::UtilError; use std::{any::Any, sync::Mutex}; use libc::{tcgetattr, tcsetattr, termios, OPOST, TCSANOW}; use log::debug; use once_cell::sync::Lazy; use vmm_sys_util::terminal::Terminal; /// Read the program version in `Cargo.toml` and concat with git commit id. pub const VERSION: &str = concat!( env!("CARGO_PKG_VERSION"), " commit-id ", include_str!(concat!(env!("OUT_DIR"), "/GIT_COMMIT")) ); pub static TERMINAL_MODE: Lazy<Mutex<Option<termios>>> = Lazy::new(|| Mutex::new(None)); pub fn set_termi_raw_mode() -> std::io::Result<()> { let tty_fd = std::io::stdin().lock().tty_fd(); // Safe because this only set the `old_term_mode` struct to zero. let mut old_term_mode: termios = unsafe { std::mem::zeroed() }; // Safe because this only get stdin's current mode and save it. let ret = unsafe { tcgetattr(tty_fd, &mut old_term_mode as *mut _) }; if ret < 0 { return Err(std::io::Error::last_os_error()); } *TERMINAL_MODE.lock().unwrap() = Some(old_term_mode); let mut new_term_mode: termios = old_term_mode; // Safe because this function only change the `new_term_mode` argument. unsafe { libc::cfmakeraw(&mut new_term_mode as *mut _) }; new_term_mode.c_oflag |= OPOST; // Safe because this function only set the stdin to raw mode. let ret = unsafe { tcsetattr(tty_fd, TCSANOW, &new_term_mode as *const _) }; if ret < 0 { return Err(std::io::Error::last_os_error()); } Ok(()) } pub fn set_termi_canon_mode() -> std::io::Result<()> { let tty_fd = std::io::stdin().lock().tty_fd(); if let Some(old_term_mode) = TERMINAL_MODE.lock().unwrap().as_ref() { // Safe because this only recover the stdin's mode. let ret = unsafe { tcsetattr(tty_fd, TCSANOW, old_term_mode as *const _) }; if ret < 0 { return Err(std::io::Error::last_os_error()); } } else { debug!("stdin's mode is not initialized: please check the config"); } Ok(()) } /// This trait is to cast trait object to struct. pub trait AsAny { fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; } impl<T: Any> AsAny for T { fn as_any(&self) -> &dyn Any { self } fn as_any_mut(&mut self) -> &mut dyn Any { self } }