summaryrefslogtreecommitdiffhomepage
path: root/src/process.rs
blob: 7143b85eb3b8419db22db8fafd8c946367d2aef3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use std::ffi::{OsString, OsStr};
use std::io;
use std::path::{Path, PathBuf};
use std::process::{Command, Child, Stdio};

/// An OpenVPN process builder, providing control over the different arguments that the OpenVPN
/// binary accepts.
pub struct OpenVpnBuilder {
    openvpn_bin: OsString,
    config: Option<PathBuf>,
}

impl OpenVpnBuilder {
    /// Constructs a new `OpenVpnBuilder` for launching OpenVPN processes from the binary at
    /// `openvpn_bin`.
    pub fn new<P: AsRef<OsStr>>(openvpn_bin: P) -> Self {
        OpenVpnBuilder {
            openvpn_bin: OsString::from(openvpn_bin.as_ref()),
            config: None,
        }
    }

    /// Sets what configuration file will be given to OpenVPN
    pub fn config<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
        self.config = Some(path.as_ref().to_path_buf());
        self
    }

    /// Executes the OpenVPN process as a child process, returning a handle to it.
    pub fn spawn(&mut self) -> io::Result<Child> {
        let mut command = self.create_command();
        self.apply_settings(&mut command);
        command.spawn()
    }

    fn create_command(&mut self) -> Command {
        let mut command = Command::new(&self.openvpn_bin);
        command.env_clear()
            .stdin(Stdio::null())
            .stdout(Stdio::null())
            .stderr(Stdio::null());
        command
    }

    fn apply_settings(&self, command: &mut Command) {
        if let Some(ref config) = self.config {
            command.arg("--config").arg(config);
        }
    }
}