1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 05:12:40 +03:00

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
```
This commit is contained in:
Wez Furlong 2022-08-09 17:27:05 -07:00
parent c496f1ce97
commit 9cd72fefe2
4 changed files with 12 additions and 3 deletions

1
Cargo.lock generated
View File

@ -3305,6 +3305,7 @@ dependencies = [
"lazy_static",
"libc",
"log",
"nix 0.24.2",
"serde",
"serde_derive",
"serial",

View File

@ -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

View File

@ -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}

View File

@ -364,7 +364,9 @@ impl CommandBuilder {
}
fn search_path(&self, exe: &OsStr, cwd: &OsStr) -> anyhow::Result<OsString> {
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()
);
}