aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.rs')
-rw-r--r--src/config.rs26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/config.rs b/src/config.rs
index 7c6cf2b..4976af3 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,8 +1,11 @@
use serde::Deserialize;
use std::fs;
+use std::os::unix::process::CommandExt;
use std::path::{Path, PathBuf};
use std::process::Command;
+use crate::util::get_invoking_user_env;
+
pub const TEMP_CONFIG_PATH: &str = "/var/lib/forge/.tmp";
pub enum ConfigCommand {
@@ -66,6 +69,9 @@ pub fn run_config_command(
command: ConfigCommand,
) -> Result<(), String> {
let config = Config::new(config_path).ok_or("config not found".to_string())?;
+
+ let is_build = matches!(command, ConfigCommand::Build);
+
let cmd = match command {
ConfigCommand::Build => config.build,
ConfigCommand::Install => config.install,
@@ -77,9 +83,23 @@ pub fn run_config_command(
let cmd_base = parts.next().ok_or("empty command".to_string())?;
let args: Vec<&str> = parts.collect();
- let status = Command::new(cmd_base)
- .args(&args)
- .current_dir(repo_path)
+ let mut command = Command::new(cmd_base);
+ command.args(&args).current_dir(repo_path);
+
+ if is_build {
+ if let Some((uid, gid, home, path)) = get_invoking_user_env() {
+ command.env("HOME", home).env("PATH", path);
+ unsafe {
+ command.pre_exec(move || {
+ nix::unistd::setgid(nix::unistd::Gid::from_raw(gid))?;
+ nix::unistd::setuid(nix::unistd::Uid::from_raw(uid))?;
+ Ok(())
+ });
+ }
+ }
+ }
+
+ let status = command
.status()
.map_err(|e| format!("failed to execute command: {}", e))?;