diff --git a/CHANGELOG.md b/CHANGELOG.md index caeee1f5..379c2002 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Cursors are now inverted when their fixed color is similar to the cell's background +- Use working directory of active process instead of shell for SpawnNewInstance action ### Fixed diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index c30765ae..85dca0ee 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -297,16 +297,20 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon #[cfg(unix)] let args = { - #[cfg(not(target_os = "freebsd"))] - let proc_prefix = ""; - #[cfg(target_os = "freebsd")] - let proc_prefix = "/compat/linux"; - let link_path = format!("{}/proc/{}/cwd", proc_prefix, tty::child_pid()); - if let Ok(path) = fs::read_link(link_path) { - vec!["--working-directory".into(), path] - } else { - Vec::new() + // Use working directory of controlling process, or fallback to initial shell. + let mut pid = unsafe { libc::tcgetpgrp(tty::master_fd()) }; + if pid < 0 { + pid = tty::child_pid(); } + + #[cfg(not(target_os = "freebsd"))] + let link_path = format!("/proc/{}/cwd", pid); + #[cfg(target_os = "freebsd")] + let link_path = format!("/compat/linux/proc/{}/cwd", pid); + + fs::read_link(link_path) + .map(|path| vec!["--working-directory".into(), path]) + .unwrap_or_default() }; #[cfg(not(unix))] let args: Vec = Vec::new(); diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs index 3998d9e6..c52da34d 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -13,7 +13,7 @@ use std::os::unix::{ }; use std::process::{Child, Command, Stdio}; use std::ptr; -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicI32, AtomicUsize, Ordering}; use libc::{self, c_int, pid_t, winsize, TIOCSCTTY}; use log::error; @@ -33,6 +33,9 @@ use crate::tty::{ChildEvent, EventedPty, EventedReadWrite}; /// Necessary to put this in static storage for `SIGCHLD` to have access. static PID: AtomicUsize = AtomicUsize::new(0); +/// File descriptor of terminal master. +static FD: AtomicI32 = AtomicI32::new(-1); + macro_rules! die { ($($arg:tt)*) => {{ error!($($arg)*); @@ -44,6 +47,10 @@ pub fn child_pid() -> pid_t { PID.load(Ordering::Relaxed) as pid_t } +pub fn master_fd() -> RawFd { + FD.load(Ordering::Relaxed) as RawFd +} + /// Get raw fds for master/slave ends of a new PTY. fn make_pty(size: winsize) -> (RawFd, RawFd) { let mut win_size = size; @@ -224,8 +231,9 @@ pub fn new(config: &Config, size: &SizeInfo, window_id: Option) -> match builder.spawn() { Ok(child) => { - // Remember child PID so other modules can use it. + // Remember master FD and child PID so other modules can use it. PID.store(child.id() as usize, Ordering::Relaxed); + FD.store(master, Ordering::Relaxed); unsafe { // Maybe this should be done outside of this function so nonblocking