diff options
| author | Emīls <emils@mullvad.net> | 2018-05-15 16:09:56 +0100 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2018-05-22 12:49:57 +0200 |
| commit | bb8a81e15382effe2cbf56d4bfb4b703b89ccff5 (patch) | |
| tree | 497e2c5aab828e07dd90e1a2e7ee0f6d46b3d37b | |
| parent | 01afa29fac8b44be0ddf0ef666fc4771069bb32b (diff) | |
| download | mullvadvpn-bb8a81e15382effe2cbf56d4bfb4b703b89ccff5.tar.xz mullvadvpn-bb8a81e15382effe2cbf56d4bfb4b703b89ccff5.zip | |
Fix shutdown behaviour on windows
| -rw-r--r-- | talpid-core/src/process/openvpn.rs | 50 | ||||
| -rw-r--r-- | talpid-core/src/process/stoppable_process.rs | 12 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/openvpn.rs | 3 |
3 files changed, 15 insertions, 50 deletions
diff --git a/talpid-core/src/process/openvpn.rs b/talpid-core/src/process/openvpn.rs index 4884b593c9..805d97c0a6 100644 --- a/talpid-core/src/process/openvpn.rs +++ b/talpid-core/src/process/openvpn.rs @@ -1,17 +1,17 @@ use duct; -extern crate os_pipe; extern crate libc; +extern crate os_pipe; +use super::stoppable_process::StoppableProcess; use std::ffi::{OsStr, OsString}; use std::fmt; use std::path::{Path, PathBuf}; -use super::stoppable_process::StoppableProcess; +use std::sync::Mutex; use self::os_pipe::{pipe, PipeWriter}; use atty; use shell_escape; use std::io; -use std::sync::{Arc, Mutex}; use talpid_types::net; static BASE_ARGUMENTS: &[&[&str]] = &[ @@ -224,19 +224,18 @@ pub struct OpenVpnProcHandle { /// Duct handle pub inner: duct::Handle, /// Standard input handle - pub stdin: PipeWriter, + pub stdin: Mutex<Option<PipeWriter>>, } /// Impl for proc handle impl OpenVpnProcHandle { - const KILL_BYTE: u8 = b'c'; /// Constructor for a new openvpn proc handle pub fn new(mut cmd: duct::Expression) -> io::Result<Self> { - if atty::is(atty::Stream::Stdout) { + if !atty::is(atty::Stream::Stdout) { cmd = cmd.stdout_null(); } - if atty::is(atty::Stream::Stderr) { + if !atty::is(atty::Stream::Stderr) { cmd = cmd.stderr_null(); } @@ -245,41 +244,18 @@ impl OpenVpnProcHandle { Ok(Self { inner: proc_handle, - stdin: writer, + stdin: Mutex::new(Some(writer)), }) } - } impl StoppableProcess for OpenVpnProcHandle { - #[cfg(unix)] /// Closes STDIN to stop the openvpn process - fn stop(&self) -> io::Result<()> { - use std::io::Error; - use std::os::unix::io::AsRawFd; - let raw_fd = self.stdin.as_raw_fd(); - unsafe { - let err = libc::close(raw_fd); - match err { - 0 => Ok(()), - err => Err(Error::from_raw_os_error(err)), - } - } - } - - #[cfg(windows)] - fn stop(&self) -> io::Result<()> { - use std::io::Error; - use std::os::unix::io::AsRawHandle; - use libc::funcs::extra::kernel32; - let raw_handle = self.stdin.as_raw_handle(); - unsafe { - let success = CloseHandle(raw_handle); - match err { - 0 => Err(Error::last_os_error()), - _ => Ok(()), - } - } + fn stop(&self) { + let mut stdin = self.stdin.lock().unwrap(); + // Dropping our stdin handle so that it is closed once. Closing the handle should + // gracefully stop our openvpn child process. + let _ = stdin.take(); } fn kill(&self) -> io::Result<()> { @@ -296,8 +272,6 @@ impl StoppableProcess for OpenVpnProcHandle { } - - #[cfg(test)] mod tests { use super::OpenVpnCommand; diff --git a/talpid-core/src/process/stoppable_process.rs b/talpid-core/src/process/stoppable_process.rs index c2d8304d85..bfd0ec3ac4 100644 --- a/talpid-core/src/process/stoppable_process.rs +++ b/talpid-core/src/process/stoppable_process.rs @@ -1,6 +1,5 @@ extern crate libc; -use std::error::Error; use std::io; use std::thread; use std::time::{Duration, Instant}; @@ -14,7 +13,7 @@ where Self: Sized, { /// Gracefully stops a process. - fn stop(&self) -> io::Result<()>; + fn stop(&self); /// Kills a process unconditionally. Implementations should strive to never fail. fn kill(&self) -> io::Result<()>; @@ -26,14 +25,7 @@ where /// process. fn nice_kill(&self, timeout: Duration) -> io::Result<()> { trace!("Trying to stop child process gracefully"); - if let Err(e) = self.stop() { - error!( - "Failed to stop the child process gracefully: {}", - e.description() - ); - return self.kill(); - }; - + self.stop(); if wait_timeout(self, timeout)? { debug!("Child process terminated gracefully"); Ok(()) diff --git a/talpid-core/src/tunnel/openvpn.rs b/talpid-core/src/tunnel/openvpn.rs index 0380f29bce..58fa15eca2 100644 --- a/talpid-core/src/tunnel/openvpn.rs +++ b/talpid-core/src/tunnel/openvpn.rs @@ -9,7 +9,6 @@ use std::process::ExitStatus; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{mpsc, Arc}; use std::thread; -#[cfg(unix)] use std::time::Duration; use talpid_ipc; @@ -32,7 +31,7 @@ mod errors { pub use self::errors::*; -static OPENVPN_DIE_TIMEOUT: Duration = Duration::from_secs(2); +static OPENVPN_DIE_TIMEOUT: Duration = Duration::from_secs(4); /// Struct for monitoring an OpenVPN process. #[derive(Debug)] |
