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 /// fn main() {
26 /// let is_elevated = Command::is_elevated();
27 ///
28 /// }
29 /// ```
30 pub fn is_elevated() -> bool {
31 let uid = unsafe {
32 libc::getuid()
33 };
34 if uid == 0 {
35 true
36 } else {
37 false
38 }
39 }
40
41 /// Prompting the user with a graphical OS dialog for the root password,
42 /// excuting the command with escalated privileges, and return the output
43 ///
44 /// # Examples
45 ///
46 /// ```no_run
47 /// use elevated_command::Command;
48 /// use std::process::Command as StdCommand;
49 ///
50 /// fn main() {
51 /// let mut cmd = StdCommand::new("path to the application");
52 /// let elevated_cmd = Command::new(cmd);
53 /// let output = elevated_cmd.output().unwrap();
54 /// }
55 /// ```
56 pub fn output(&self) -> Result<Output> {
57 let pkexec = PathBuf::from_str("/bin/pkexec")?;
58 let mut command = StdCommand::new(pkexec);
59 let display = env::var("DISPLAY");
60 let xauthority = env::var("XAUTHORITY");
61 let home = env::var("HOME");
62
63 command.arg("--disable-internal-agent");
64 if display.is_ok() || xauthority.is_ok() || home.is_ok() {
65 command.arg("env");
66 if let Ok(display) = display {
67 command.arg(format!("DISPLAY={}", display));
68 }
69 if let Ok(xauthority) = xauthority {
70 command.arg(format!("XAUTHORITY={}", xauthority));
71 }
72 if let Ok(home) = home {
73 command.arg(format!("HOME={}", home));
74 }
75 } else {
76 if self.cmd.get_envs().any(|(_, v)| v.is_some()) {
77 command.arg("env");
78 }
79 }
80 for (k, v) in self.cmd.get_envs() {
81 if let Some(value) = v {
82 command.arg(format!("{}={}",
83 k.to_str().ok_or(anyhow!("invalid key"))?,
84 value.to_str().ok_or(anyhow!("invalid value"))?
85 ));
86 }
87 }
88
89 command.arg(self.cmd.get_program());
90 let args: Vec<&OsStr> = self.cmd.get_args().collect();
91 if !args.is_empty() {
92 command.args(args);
93 }
94
95 let output = command.output()?;
96 Ok(output)
97 }
98}