diff --git a/init/src/main.rs b/init/src/main.rs index 221b7979ea..4f646d042d 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -54,6 +54,21 @@ impl InitConfig { fn switch_root(unit_store: &mut UnitStore, config: &mut InitConfig, prefix: &Path, etcdir: &Path) { status_ok(&format!("switchroot to {} {}", prefix.display(), etcdir.display())); + // Point init's working directory at the new root. There is no real chroot + // in Redox, so without this init's CWD stays unset and every daemon spawned + // after the switch inherits an invalid CWD (via AT_REDOX_CWD_FD). That made + // getcwd() fail in /usr binaries — e.g. the 00_base-env `zsh -c` setup + // service printed "zsh: Failed to get current directory: path invalid" and + // then HUNG, so init (which waits on that oneshot) never reached the login + // stack (ptyd/getty/login). Establishing a valid CWD here fixes both. + if let Err(err) = std::env::set_current_dir(prefix) { + init_warn(&format!( + "failed to chdir to new root {}: {}", + prefix.display(), + err + )); + } + config .envs .insert("PATH".to_owned(), prefix.join("bin").into_os_string());