use std::fs::OpenOptions;
use std::io::Write;
fn main() {
let mut source_list = OpenOptions::new()
.write(true)
.append(true)
.open("/usr/local/etc/apt/sources.list")
.unwrap();
if let Err(e) = writeln!(source_list, "{}", "deb ".to_owned() + "https://www.google.com/" + " ./") {
eprintln!("Couldn't write to file: {}", e);
}
}
When running this code without sudo it outputs:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', src/libcore/result.rs:999:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
and when running this code with sudo it asks for my password and then writes to the file successfully so my question is how do I get it to ask for me my password then write to the file successfully without the need of sudo (Basically how do I make it run sudo for the user so they don't have to)?
Yes you could, but if you should is another question...
When detecting the lack of privileges you could restart your program with sudo with std::process::Command
and unix is extensions exec
by executing a command with the same cmdline arguments. env::args
is an iterator to all command line arguments where the first one is the program name
use std::process::Command;
use std::os::unix::process::CommandExt;
[...]
// when restart as root is needed
let cmdlineargs:Vec<String>=env::args().collect();
let _output = Command::new("sudo")
.args(&cmdlineargs)
.exec(); // Bye bye never returns
There are a ton of problems with the code above, for instance you should avoid having the program to restart itself in an indefinite loop and hiding privilege escalations from users is often considered bad design.
Edit: Updated after suggestions in comments replaced spawn
with exec