summaryrefslogtreecommitdiffhomepage
path: root/talpid_cli/src
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-02-09 11:18:52 +0100
committerLinus Färnstrand <linus@mullvad.net>2017-02-09 11:18:52 +0100
commit82890bc9840f77973fa7c48d72d9e51004c75f40 (patch)
treedc75d9ad991d368ebe6dbd6bac591e813fe228dd /talpid_cli/src
parentb460c4c138ad283746e12604975d9d1235381ed4 (diff)
parent9d551d691a5b9981fb2c1d80801031889ca022a0 (diff)
downloadmullvadvpn-82890bc9840f77973fa7c48d72d9e51004c75f40.tar.xz
mullvadvpn-82890bc9840f77973fa7c48d72d9e51004c75f40.zip
Merge branch 'error-chain'
Diffstat (limited to 'talpid_cli/src')
-rw-r--r--talpid_cli/src/main.rs54
1 files changed, 35 insertions, 19 deletions
diff --git a/talpid_cli/src/main.rs b/talpid_cli/src/main.rs
index a174d7ed37..4a4239f622 100644
--- a/talpid_cli/src/main.rs
+++ b/talpid_cli/src/main.rs
@@ -1,34 +1,49 @@
+// `error_chain!` can recurse deeply
+#![recursion_limit = "1024"]
+
extern crate talpid_core;
#[macro_use]
extern crate clap;
+#[macro_use]
+extern crate error_chain;
use std::io::{self, Read, Write};
use std::sync::mpsc::{self, Receiver};
use std::thread;
use talpid_core::process::OpenVpnCommand;
-use talpid_core::process::monitor::{ChildMonitor, TransitionResult, ChildSpawner};
+use talpid_core::process::monitor::{ChildMonitor, ChildSpawner};
mod cli;
use cli::Args;
-/// Macro for printing to stderr. Will simply do nothing if the printing fails for some reason.
-macro_rules! eprintln {
- ($($arg:tt)*) => (
- use std::io::Write;
- let _ = writeln!(&mut ::std::io::stderr(), $($arg)* );
- )
+
+error_chain! {
+ links {
+ Monitor(talpid_core::process::monitor::Error, talpid_core::process::monitor::ErrorKind);
+ }
}
+
fn main() {
- let args = cli::parse_args_or_exit();
+ if let Err(ref e) = run() {
+ println!("error: {}", e);
+ for e in e.iter().skip(1) {
+ println!("caused by: {}", e);
+ }
+ if let Some(backtrace) = e.backtrace() {
+ println!("backtrace: {:?}", backtrace);
+ }
+ ::std::process::exit(1);
+ }
+}
+fn run() -> Result<()> {
+ let args = cli::parse_args_or_exit();
let command = create_openvpn_command(&args);
let monitor = ChildMonitor::new(command);
- if let Err(e) = main_loop(monitor) {
- eprintln!("OpenVPN failed: {}", e);
- }
+ main_loop(monitor)
}
fn create_openvpn_command(args: &Args) -> OpenVpnCommand {
@@ -41,27 +56,28 @@ fn create_openvpn_command(args: &Args) -> OpenVpnCommand {
command
}
-fn main_loop<S>(mut monitor: ChildMonitor<S>) -> TransitionResult<()>
+fn main_loop<S>(mut monitor: ChildMonitor<S>) -> Result<()>
where S: ChildSpawner
{
loop {
- let rx = start_monitor(&mut monitor)?;
+ let rx = start_monitor(&mut monitor).chain_err(|| "Unable to start OpenVPN")?;
let clean_exit = rx.recv().unwrap();
println!("Monitored process exited. clean: {}", clean_exit);
std::thread::sleep(std::time::Duration::from_millis(500));
}
}
-fn start_monitor<S>(monitor: &mut ChildMonitor<S>) -> TransitionResult<Receiver<bool>>
+fn start_monitor<S>(monitor: &mut ChildMonitor<S>) -> Result<Receiver<bool>>
where S: ChildSpawner
{
let (tx, rx) = mpsc::channel();
let callback = move |clean| tx.send(clean).unwrap();
- monitor.start(callback).map(|(stdout, stderr)| {
- stdout.map(|stream| pass_io(stream, io::stdout()));
- stderr.map(|stream| pass_io(stream, io::stderr()));
- rx
- })
+ Ok(monitor.start(callback)
+ .map(|(stdout, stderr)| {
+ stdout.map(|stream| pass_io(stream, io::stdout()));
+ stderr.map(|stream| pass_io(stream, io::stderr()));
+ rx
+ })?)
}
fn pass_io<I, O>(mut input: I, mut output: O)