From 9cd72fefe222b4b753517fce5d8be25380ed2c41 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Tue, 9 Aug 2022 17:27:05 -0700 Subject: [PATCH] pty: cmdbuilder: check for executable access when resolving program `wezterm start -- /etc/profile` would crash on macOS because `/etc/profile` isn't executable. This commit checks for executable access as a prereq for both the path search and the absolute path cases and generates a non-crashing error: ``` $ wezterm start -- /etc/profile 17:24:03.574 ERROR wezterm_gui > Unable to spawn /etc/profile because it doesn't exist on the filesystem or is not executable (EACCES: Permission denied); terminating ``` --- Cargo.lock | 1 + docs/changelog.md | 4 ++++ pty/Cargo.toml | 1 + pty/src/cmdbuilder.rs | 9 ++++++--- 4 files changed, 12 insertions(+), 3 deletions(-) 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() ); }