Skip to content

Commit

Permalink
Merge branch 'login-shell-fix' into windows-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nzbr committed May 8, 2024
2 parents 2e63f3b + 473eda6 commit 5e16faa
Showing 1 changed file with 57 additions and 28 deletions.
85 changes: 57 additions & 28 deletions utils/src/shell_wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use anyhow::{anyhow, Context};
use nix::libc::{sigaction, PT_NULL, SIGCHLD, SIG_IGN};
use std::mem::MaybeUninit;
use std::os::unix::process::CommandExt;
use std::process::Command;
use std::{env, fs::read_link};
Expand All @@ -18,33 +20,53 @@ fn real_main() -> anyhow::Result<()> {

// Skip if environment was already set
if env::var_os("__NIXOS_SET_ENVIRONMENT_DONE") != Some("1".into()) {
// Load the environment from /etc/set-environment
let output = Command::new(env!("NIXOS_WSL_SH"))
.args(&[
"-c",
&format!(". /etc/set-environment && {} -0", env!("NIXOS_WSL_ENV")),
])
.output()
.context("when reading /etc/set-environment")?;

// Parse the output
let output_string =
String::from_utf8(output.stdout).context("when decoding the output of env")?;
let env = output_string
.split('\0')
.filter(|entry| !entry.is_empty())
.map(|entry| {
entry
.split_once("=")
.ok_or(anyhow!("invalid env entry: {}", entry))
})
.collect::<Result<Vec<_>, _>>()
.context("when parsing the output of env")?;

// Apply the environment variables
for &(key, val) in &env {
env::set_var(key, val);
}
|| -> anyhow::Result<()> {
if !std::path::Path::new("/etc/set-environment").exists() {
eprintln!("[shell-wrapper] Warning: /etc/set-environment does not exist");
return Ok(());
}

unsafe {
// WSL starts a single shell under login to make sure that a logind session exists.
// That shell is started with SIGCHLD ignored
// If it is, we are probably that shell and can just skip setting the environment
let mut act: sigaction = MaybeUninit::zeroed().assume_init();
sigaction(SIGCHLD, PT_NULL as *const sigaction, &mut act);
if act.sa_sigaction == SIG_IGN {
return Ok(());
}
}

// Load the environment from /etc/set-environment
let output = Command::new(env!("NIXOS_WSL_SH"))
.args(&[
"-c",
&format!(". /etc/set-environment && {} -0", env!("NIXOS_WSL_ENV")),
])
.output()
.context("when reading /etc/set-environment")?;

// Parse the output
let output_string =
String::from_utf8(output.stdout).context("when decoding the output of env")?;
let env = output_string
.split('\0')
.filter(|entry| !entry.is_empty())
.map(|entry| {
entry
.split_once("=")
.ok_or(anyhow!("invalid env entry: {}", entry))
})
.collect::<Result<Vec<_>, _>>()
.context("when parsing the output of env")?;

// Apply the environment variables
for &(key, val) in &env {
env::set_var(key, val);
}

Ok(())
}()?;
}

let shell_exe = &shell
Expand Down Expand Up @@ -77,5 +99,12 @@ fn main() {
let result = real_main();

env::set_var("RUST_BACKTRACE", "1");
eprintln!("[shell-wrapper] Error: {:?}", result.unwrap_err());
let err = result.unwrap_err();

eprintln!("[shell-wrapper] Error: {:?}", &err);

// Write the result to /tmp/shell-wrapper_crash_<pid>.log
let pid = std::process::id();
let output_file = format!("/tmp/shell-wrapper_crash_{}.log", pid);
std::fs::write(output_file, format!("{:?}", &err)).expect("Failed to write crash log to file");
}

0 comments on commit 5e16faa

Please sign in to comment.