aboutsummaryrefslogtreecommitdiff
path: root/winpty/src/windows.rs
diff options
context:
space:
mode:
Diffstat (limited to 'winpty/src/windows.rs')
-rw-r--r--winpty/src/windows.rs116
1 files changed, 40 insertions, 76 deletions
diff --git a/winpty/src/windows.rs b/winpty/src/windows.rs
index ada8bb0d..27780d4f 100644
--- a/winpty/src/windows.rs
+++ b/winpty/src/windows.rs
@@ -20,17 +20,20 @@ pub enum ErrorCodes {
AgentTimeout,
AgentCreationFailed,
}
+
pub enum MouseMode {
None,
Auto,
Force,
}
+
bitflags!(
pub struct SpawnFlags: u64 {
const AUTO_SHUTDOWN = 0x1;
const EXIT_AFTER_SHUTDOWN = 0x2;
}
);
+
bitflags!(
pub struct ConfigFlags: u64 {
const CONERR = 0x1;
@@ -40,42 +43,32 @@ bitflags!(
);
#[derive(Debug)]
-pub struct Err<'a> {
- ptr: &'a mut winpty_error_t,
+pub struct Err {
code: u32,
message: String,
}
-// Check to see whether winpty gave us an error
-fn check_err<'a>(e: *mut winpty_error_t) -> Option<Err<'a>> {
- let err = unsafe {
+// Check to see whether winpty gave us an error, and perform the necessary memory freeing
+fn check_err(e: *mut winpty_error_t) -> Option<Err> {
+ unsafe {
+ let code = winpty_error_code(e);
let raw = winpty_error_msg(e);
- Err {
- ptr: &mut *e,
- code: winpty_error_code(e),
- message: String::from_utf16_lossy(std::slice::from_raw_parts(raw, wcslen(raw))),
+ let message = String::from_utf16_lossy(std::slice::from_raw_parts(raw, wcslen(raw)));
+ winpty_error_free(e);
+ match code {
+ 0 => None,
+ _ => Some(Err { code, message }),
}
- };
- if err.code == 0 {
- None
- } else {
- Some(err)
}
}
-impl<'a> Drop for Err<'a> {
- fn drop(&mut self) {
- unsafe {
- winpty_error_free(self.ptr);
- }
- }
-}
-impl<'a> Display for Err<'a> {
+impl Display for Err {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
write!(f, "Code: {}, Message: {}", self.code, self.message)
}
}
-impl<'a> Error for Err<'a> {
+
+impl Error for Err {
fn description(&self) -> &str {
&self.message
}
@@ -83,18 +76,13 @@ impl<'a> Error for Err<'a> {
#[derive(Debug)]
/// Winpty agent config
-pub struct Config<'a>(&'a mut winpty_config_t);
+pub struct Config(*mut winpty_config_t);
-impl<'a, 'b> Config<'a> {
- pub fn new(flags: ConfigFlags) -> Result<Self, Err<'b>> {
+impl Config {
+ pub fn new(flags: ConfigFlags) -> Result<Self, Err> {
let mut err = null_mut() as *mut winpty_error_t;
let config = unsafe { winpty_config_new(flags.bits(), &mut err) };
-
- if let Some(err) = check_err(err) {
- Result::Err(err)
- } else {
- unsafe { Ok(Config(&mut *config)) }
- }
+ check_err(err).map_or(Ok(Self(config)), Result::Err)
}
/// Set the initial size of the console window
@@ -127,7 +115,7 @@ impl<'a, 'b> Config<'a> {
}
}
-impl<'a> Drop for Config<'a> {
+impl Drop for Config {
fn drop(&mut self) {
unsafe {
winpty_config_free(self.0);
@@ -137,23 +125,16 @@ impl<'a> Drop for Config<'a> {
#[derive(Debug)]
/// A struct representing the winpty agent process
-pub struct Winpty<'a>(&'a mut winpty_t);
+pub struct Winpty(*mut winpty_t);
-impl<'a, 'b> Winpty<'a> {
+impl Winpty {
/// Starts the agent. This process will connect to the agent
/// over a control pipe, and the agent will open data pipes
/// (e.g. CONIN and CONOUT).
- pub fn open(cfg: &Config) -> Result<Self, Err<'b>> {
+ pub fn open(cfg: &Config) -> Result<Self, Err> {
let mut err = null_mut() as *mut winpty_error_t;
- unsafe {
- let winpty = winpty_open(cfg.0, &mut err);
- let err = check_err(err);
- if let Some(err) = err {
- Result::Err(err)
- } else {
- Ok(Winpty(&mut *winpty))
- }
- }
+ let winpty = unsafe { winpty_open(cfg.0, &mut err) };
+ check_err(err).map_or(Ok(Self(winpty)), Result::Err)
}
/// Returns the handle to the winpty agent process
@@ -200,11 +181,7 @@ impl<'a, 'b> Winpty<'a> {
winpty_set_size(self.0, i32::from(cols), i32::from(rows), &mut err);
}
- if let Some(err) = check_err(err) {
- Result::Err(err)
- } else {
- Ok(())
- }
+ check_err(err).map_or(Ok(()), Result::Err)
}
/// Get the list of processes running in the winpty agent. Returns <= count processes
@@ -227,11 +204,7 @@ impl<'a, 'b> Winpty<'a> {
process_list.set_len(len);
}
- if let Some(err) = check_err(err) {
- Result::Err(err)
- } else {
- Ok(process_list)
- }
+ check_err(err).map_or(Ok(process_list), Result::Err)
}
/// Spawns the new process.
@@ -259,19 +232,15 @@ impl<'a, 'b> Winpty<'a> {
}
}
- if let Some(err) = check_err(err) {
- Result::Err(err)
- } else {
- Ok(())
- }
+ check_err(err).map_or(Ok(()), Result::Err)
}
}
// winpty_t is thread-safe
-unsafe impl<'a> Sync for Winpty<'a> {}
-unsafe impl<'a> Send for Winpty<'a> {}
+unsafe impl Sync for Winpty {}
+unsafe impl Send for Winpty {}
-impl<'a> Drop for Winpty<'a> {
+impl Drop for Winpty {
fn drop(&mut self) {
unsafe {
winpty_free(self.0);
@@ -281,9 +250,9 @@ impl<'a> Drop for Winpty<'a> {
#[derive(Debug)]
/// Information about a process for winpty to spawn
-pub struct SpawnConfig<'a>(&'a mut winpty_spawn_config_t);
+pub struct SpawnConfig(*mut winpty_spawn_config_t);
-impl<'a, 'b> SpawnConfig<'a> {
+impl SpawnConfig {
/// Creates a new spawnconfig
pub fn new(
spawnflags: SpawnFlags,
@@ -291,7 +260,7 @@ impl<'a, 'b> SpawnConfig<'a> {
cmdline: Option<&str>,
cwd: Option<&str>,
end: Option<&str>,
- ) -> Result<Self, Err<'b>> {
+ ) -> Result<Self, Err> {
let mut err = null_mut() as *mut winpty_error_t;
let (appname, cmdline, cwd, end) = (
appname.map_or(null(), |s| WideCString::from_str(s).unwrap().into_raw()),
@@ -320,14 +289,11 @@ impl<'a, 'b> SpawnConfig<'a> {
}
}
- if let Some(err) = check_err(err) {
- Result::Err(err)
- } else {
- unsafe { Ok(SpawnConfig(&mut *spawn_config)) }
- }
+ check_err(err).map_or(Ok(Self(spawn_config)), Result::Err)
}
}
-impl<'a> Drop for SpawnConfig<'a> {
+
+impl Drop for SpawnConfig {
fn drop(&mut self) {
unsafe {
winpty_spawn_config_free(self.0);
@@ -338,10 +304,8 @@ impl<'a> Drop for SpawnConfig<'a> {
#[cfg(test)]
mod tests {
use named_pipe::PipeClient;
- use winapi;
-
- use self::winapi::um::processthreadsapi::OpenProcess;
- use self::winapi::um::winnt::READ_CONTROL;
+ use winapi::um::processthreadsapi::OpenProcess;
+ use winapi::um::winnt::READ_CONTROL;
use crate::{Config, ConfigFlags, SpawnConfig, SpawnFlags, Winpty};