diff --git a/Cargo.lock b/Cargo.lock index d5a4d087b..32aa11917 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3305,6 +3305,7 @@ dependencies = [ "lazy_static", "libc", "log", + "nix 0.24.2", "serde", "serde_derive", "serial", diff --git a/docs/changelog.md b/docs/changelog.md index e199553e8..b43938c19 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -19,6 +19,10 @@ As features stabilize some brief notes about them will accumulate here. * [ActivatePaneDirection](config/lua/keyassignment/ActivatePaneDirection.md) now uses recency to resolve ambiguous moves [#2374](https://github.com/wez/wezterm/issues/2374) +#### Fixed + +* macOS: crash on startup if `$SHELL` points to something that isn't executable. [#2378](https://github.com/wez/wezterm/issues/2378) + ### 20220807-113146-c2fee766 #### New diff --git a/pty/Cargo.toml b/pty/Cargo.toml index 2df06b4b9..8c1661d55 100644 --- a/pty/Cargo.toml +++ b/pty/Cargo.toml @@ -14,6 +14,7 @@ downcast-rs = "1.0" filedescriptor = { version="0.8", path = "../filedescriptor" } log = "0.4" libc = "0.2" +nix = "0.24" shell-words = "1.1" serde_derive = {version="1.0", optional=true} serde = {version="1.0", optional=true} diff --git a/pty/src/cmdbuilder.rs b/pty/src/cmdbuilder.rs index 490f8f7db..cb65949ed 100644 --- a/pty/src/cmdbuilder.rs +++ b/pty/src/cmdbuilder.rs @@ -364,7 +364,9 @@ impl CommandBuilder { } fn search_path(&self, exe: &OsStr, cwd: &OsStr) -> anyhow::Result { + use nix::unistd::{access, AccessFlags}; use std::path::Path; + let exe_path: &Path = exe.as_ref(); if exe_path.is_relative() { let cwd: &Path = cwd.as_ref(); @@ -376,7 +378,7 @@ impl CommandBuilder { if let Some(path) = self.resolve_path() { for path in std::env::split_paths(&path) { let candidate = path.join(&exe); - if candidate.exists() { + if access(&candidate, AccessFlags::X_OK).is_ok() { return Ok(candidate.into_os_string()); } } @@ -387,9 +389,10 @@ impl CommandBuilder { exe_path.display() ); } else { - if !exe_path.exists() { + if let Err(err) = access(exe_path, AccessFlags::X_OK) { anyhow::bail!( - "Unable to spawn {} because it doesn't exist on the filesystem", + "Unable to spawn {} because it doesn't exist on the filesystem \ + or is not executable ({err:#})", exe_path.display() ); }