1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2025-04-07 17:43:03 -04:00

Dont fail exec() on deleted directories

Use the `std::env::set_current_dir` from the `pre_exec` and ignore
error, since not changing working directory is a side effect which
shouldn't break spawning a program or block window creation.

Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
Co-authored-by: Christian Duerr <contact@christianduerr.com>
This commit is contained in:
Tycho Andersen 2025-02-08 03:01:56 -05:00 committed by Christian Duerr
parent 5addcb99a8
commit 3d46335174
4 changed files with 19 additions and 13 deletions

View file

@ -18,6 +18,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its
### Fixed
- Modifiers being out of sync for fast/synthetic input on X11
- Child process creation failing while inside a deleted directory
## 0.15.0

View file

@ -9,6 +9,7 @@ use std::process::{Command, Stdio};
#[rustfmt::skip]
#[cfg(not(windows))]
use {
std::env,
std::error::Error,
std::os::unix::process::CommandExt,
std::os::unix::io::RawFd,
@ -58,18 +59,22 @@ where
{
let mut command = Command::new(program);
command.args(args).stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::null());
if let Ok(cwd) = foreground_process_path(master_fd, shell_pid) {
command.current_dir(cwd);
}
let working_directory = foreground_process_path(master_fd, shell_pid).ok();
unsafe {
command
.pre_exec(|| {
.pre_exec(move || {
match libc::fork() {
-1 => return Err(io::Error::last_os_error()),
0 => (),
_ => libc::_exit(0),
}
// Copy foreground process' working directory, ignoring invalid paths.
if let Some(working_directory) = working_directory.as_ref() {
let _ = env::set_current_dir(working_directory);
}
if libc::setsid() == -1 {
return Err(io::Error::last_os_error());
}

View file

@ -844,9 +844,8 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
#[cfg(not(windows))]
fn create_new_window(&mut self, #[cfg(target_os = "macos")] tabbing_id: Option<String>) {
let mut options = WindowOptions::default();
if let Ok(working_directory) = foreground_process_path(self.master_fd, self.shell_pid) {
options.terminal_options.working_directory = Some(working_directory);
}
options.terminal_options.working_directory =
foreground_process_path(self.master_fd, self.shell_pid).ok();
#[cfg(target_os = "macos")]
{
@ -875,7 +874,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
match result {
Ok(_) => debug!("Launched {} with args {:?}", program, args),
Err(_) => warn!("Unable to launch {} with args {:?}", program, args),
Err(err) => warn!("Unable to launch {program} with args {args:?}: {err}"),
}
}

View file

@ -231,6 +231,7 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd
builder.env_remove("XDG_ACTIVATION_TOKEN");
builder.env_remove("DESKTOP_STARTUP_ID");
let working_directory = config.working_directory.clone();
unsafe {
builder.pre_exec(move || {
// Create a new process group.
@ -239,6 +240,11 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd
return Err(Error::new(ErrorKind::Other, "Failed to set session id"));
}
// Set working directory, ignoring invalid paths.
if let Some(working_directory) = working_directory.as_ref() {
let _ = env::set_current_dir(working_directory);
}
set_controlling_terminal(slave_fd);
// No longer need slave/master fds.
@ -256,11 +262,6 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd
});
}
// Handle set working directory option.
if let Some(dir) = &config.working_directory {
builder.current_dir(dir);
}
// Prepare signal handling before spawning child.
let (signals, sig_id) = {
let (sender, recv) = UnixStream::pair()?;