aboutsummaryrefslogtreecommitdiff
path: root/libs/nak/src/runtime_wrap.rs
blob: 943a329f3c94a33a30766f2de54672be7bc9c753 (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
51
52
53
54
55
56
57
58
use std::ffi::OsStr;
use std::process::Command;

/// Build a command to run `exe` with the given environment variables.
///
/// If SLR (Steam Linux Runtime) is installed, the command is wrapped inside
/// the pressure-vessel container via the SLR `run` script.  Environment
/// variables are set on the process and inherited by pressure-vessel into the
/// container (matching how game launches work via QProcess).  This ensures
/// Wine/Proton commands use the container's libraries instead of potentially
/// broken host libraries.
pub fn build_command<S: AsRef<OsStr>>(
    exe: impl AsRef<OsStr>,
    envs: &[(&str, S)],
) -> Command {
    if let Some(slr_script) = crate::slr::get_slr_run_script() {
        let mut cmd = Command::new(&slr_script);
        // Set env vars on the process — pressure-vessel inherits them
        for (key, value) in envs {
            cmd.env(key, value.as_ref());
        }
        // Expose the executable's parent directory to the container —
        // needed for system-installed Protons (e.g. /usr/share/steam/...)
        // whose files may not be visible inside the container by default.
        if let Some(parent) = std::path::Path::new(exe.as_ref()).parent() {
            if parent.exists() {
                let mut flag = std::ffi::OsString::from("--filesystem=");
                flag.push(parent.as_os_str());
                cmd.arg(flag);
            }
        }
        // Also expose WINEPREFIX if set in env vars
        for (key, value) in envs {
            if *key == "WINEPREFIX" || *key == "STEAM_COMPAT_DATA_PATH" {
                let path = std::path::Path::new(value.as_ref());
                if path.exists() || path.parent().map_or(false, |p| p.exists()) {
                    let mut flag = std::ffi::OsString::from("--filesystem=");
                    flag.push(value.as_ref());
                    cmd.arg(flag);
                }
            }
        }
        cmd.arg("--");
        cmd.arg(exe);
        cmd
    } else {
        let mut cmd = Command::new(exe);
        for (key, value) in envs {
            cmd.env(key, value.as_ref());
        }
        cmd
    }
}

/// Build a command with no extra environment variables.
pub fn command_for(exe: impl AsRef<OsStr>) -> Command {
    build_command::<&str>(exe, &[])
}