elevated_command/linux.rs
1/*---------------------------------------------------------------------------------------------
2 * Copyright (c) Luis Liu. All rights reserved.
3 * Licensed under the MIT License. See License in the project root for license information.
4 *--------------------------------------------------------------------------------------------*/
5
6use crate::Command;
7use anyhow::{anyhow, Result};
8use std::env;
9use std::ffi::OsStr;
10use std::path::PathBuf;
11use std::process::{Command as StdCommand, Output};
12use std::str::FromStr;
13
14/// The implementation of state check and elevated executing varies on each platform
15impl Command {
16 /// Check the state the current program running
17 ///
18 /// Return `true` if the program is running as root, otherwise false
19 ///
20 /// # Examples
21 ///
22 /// ```no_run
23 /// use elevated_command::Command;
24 ///
25 /// let is_elevated = Command::is_elevated();
26 /// ```
27 pub fn is_elevated() -> bool {
28 let uid = unsafe { libc::getuid() };
29 if uid == 0 {
30 true
31 } else {
32 false
33 }
34 }
35
36 /// Prompting the user with a graphical OS dialog for the root password,
37 /// excuting the command with escalated privileges, and return the output
38 ///
39 /// # Examples
40 ///
41 /// ```no_run
42 /// use elevated_command::Command;
43 /// use std::process::Command as StdCommand;
44 ///
45 /// let mut cmd = StdCommand::new("path to the application");
46 /// let elevated_cmd = Command::new(cmd);
47 /// let output = elevated_cmd.output().unwrap();
48 /// ```
49 pub fn output(&self) -> Result<Output> {
50 let mut command = StdCommand::new("pkexec");
51 let display = env::var("DISPLAY");
52 let xauthority = env::var("XAUTHORITY");
53 let home = env::var("HOME");
54
55 command.arg("--disable-internal-agent");
56 if display.is_ok() || xauthority.is_ok() || home.is_ok() {
57 command.arg("env");
58 if let Ok(display) = display {
59 command.arg(format!("DISPLAY={}", display));
60 }
61 if let Ok(xauthority) = xauthority {
62 command.arg(format!("XAUTHORITY={}", xauthority));
63 }
64 if let Ok(home) = home {
65 command.arg(format!("HOME={}", home));
66 }
67 } else {
68 if self.cmd.get_envs().any(|(_, v)| v.is_some()) {
69 command.arg("env");
70 }
71 }
72 for (k, v) in self.cmd.get_envs() {
73 if let Some(value) = v {
74 command.arg(format!(
75 "{}={}",
76 k.to_str().ok_or(anyhow!("invalid key"))?,
77 value.to_str().ok_or(anyhow!("invalid value"))?
78 ));
79 }
80 }
81
82 command.arg(self.cmd.get_program());
83 let args: Vec<&OsStr> = self.cmd.get_args().collect();
84 if !args.is_empty() {
85 command.args(args);
86 }
87
88 let output = command.output()?;
89 Ok(output)
90 }
91}