summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Carrasco <carrascomurielj@gmail.com>2021-12-18 18:27:10 +0100
committerGitHub <noreply@github.com>2021-12-18 17:27:10 +0000
commitf1802c1cda7b9922f23d872705653beb6b053f2e (patch)
tree94563436c88ac16457ad084dd2f045295cf29819
parentcded85a2f2c1c554d64bae285ccd8f9815468d4d (diff)
Spawn children from foreground working directory
To allow applications spawned by Alacritty to make use of the shell/foreground process' working directory, it is now set for all new processes spawned by Alacritty on Unix platforms. Fixes #5616. Co-authored-by: Christian Duerr <contact@christianduerr.com>
-rw-r--r--CHANGELOG.md1
-rw-r--r--alacritty/src/daemon.rs45
-rw-r--r--alacritty/src/event.rs47
3 files changed, 49 insertions, 44 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64cd7c5e..69623b97 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Reload configuration files when their symbolic link is replaced
- Strip trailing whitespaces when yanking from a block selection
- Display area keeps history position when viewport is cleared
+- Commands spawn from the current directory of the foreground shell in Unix-like systems
### Fixed
diff --git a/alacritty/src/daemon.rs b/alacritty/src/daemon.rs
index b199c353..4b95cb6b 100644
--- a/alacritty/src/daemon.rs
+++ b/alacritty/src/daemon.rs
@@ -1,16 +1,28 @@
+#[cfg(not(windows))]
+use std::error::Error;
use std::ffi::OsStr;
use std::fmt::Debug;
+#[cfg(not(any(target_os = "macos", windows)))]
+use std::fs;
use std::io;
#[cfg(not(windows))]
use std::os::unix::process::CommandExt;
#[cfg(windows)]
use std::os::windows::process::CommandExt;
+#[cfg(not(windows))]
+use std::path::PathBuf;
use std::process::{Command, Stdio};
use log::{debug, warn};
#[cfg(windows)]
use winapi::um::winbase::{CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW};
+#[cfg(not(windows))]
+use alacritty_terminal::tty;
+
+#[cfg(target_os = "macos")]
+use crate::macos;
+
/// Start the daemon and log error on failure.
pub fn start_daemon<I, S>(program: &str, args: I)
where
@@ -43,18 +55,41 @@ where
.map(|_| ())
}
+/// Get working directory of controlling process.
+#[cfg(not(windows))]
+pub fn foreground_process_path() -> Result<PathBuf, Box<dyn Error>> {
+ let mut pid = unsafe { libc::tcgetpgrp(tty::master_fd()) };
+ if pid < 0 {
+ pid = tty::child_pid();
+ }
+
+ #[cfg(not(any(target_os = "macos", target_os = "freebsd")))]
+ let link_path = format!("/proc/{}/cwd", pid);
+ #[cfg(target_os = "freebsd")]
+ let link_path = format!("/compat/linux/proc/{}/cwd", pid);
+
+ #[cfg(not(target_os = "macos"))]
+ let cwd = fs::read_link(link_path)?;
+
+ #[cfg(target_os = "macos")]
+ let cwd = macos::proc::cwd(pid)?;
+
+ Ok(cwd)
+}
+
#[cfg(not(windows))]
fn spawn_daemon<I, S>(program: &str, args: I) -> io::Result<()>
where
I: IntoIterator<Item = S> + Copy,
S: AsRef<OsStr>,
{
+ 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() {
+ command.current_dir(cwd);
+ }
unsafe {
- Command::new(program)
- .args(args)
- .stdin(Stdio::null())
- .stdout(Stdio::null())
- .stderr(Stdio::null())
+ command
.pre_exec(|| {
match libc::fork() {
-1 => return Err(io::Error::last_os_error()),
diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs
index 4af372c9..7fb54b39 100644
--- a/alacritty/src/event.rs
+++ b/alacritty/src/event.rs
@@ -30,20 +30,18 @@ use alacritty_terminal::index::{Boundary, Column, Direction, Line, Point, Side};
use alacritty_terminal::selection::{Selection, SelectionType};
use alacritty_terminal::term::search::{Match, RegexSearch};
use alacritty_terminal::term::{ClipboardType, SizeInfo, Term, TermMode};
-#[cfg(not(windows))]
-use alacritty_terminal::tty;
use crate::cli::{Options as CliOptions, TerminalOptions as TerminalCliOptions};
use crate::clipboard::Clipboard;
use crate::config::ui_config::{HintAction, HintInternalAction};
use crate::config::{self, UiConfig};
+#[cfg(not(windows))]
+use crate::daemon::foreground_process_path;
use crate::daemon::start_daemon;
use crate::display::hint::HintMatch;
use crate::display::window::Window;
use crate::display::{self, Display};
use crate::input::{self, ActionContext as _, FONT_SIZE_STEP};
-#[cfg(target_os = "macos")]
-use crate::macos;
use crate::message_bar::{Message, MessageBuffer};
use crate::scheduler::{Scheduler, TimerId, Topic};
use crate::window_context::WindowContext;
@@ -354,27 +352,19 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
let mut env_args = env::args();
let alacritty = env_args.next().unwrap();
- // Use working directory of controlling process, or fallback to initial shell, then add it
- // as working-directory parameter.
- #[cfg(unix)]
- let mut args = foreground_process_path()
- .map(|path| vec!["--working-directory".into(), path])
- .unwrap_or_default();
-
- #[cfg(not(unix))]
- let mut args: Vec<PathBuf> = Vec::new();
-
- let working_directory_set = !args.is_empty();
+ let mut args: Vec<String> = Vec::new();
// Reuse the arguments passed to Alacritty for the new instance.
+ #[allow(clippy::while_let_on_iterator)]
while let Some(arg) = env_args.next() {
- // Drop working directory from existing parameters.
- if working_directory_set && arg == "--working-directory" {
+ // On unix, the working directory of the foreground shell is used by `start_daemon`.
+ #[cfg(not(windows))]
+ if arg == "--working-directory" {
let _ = env_args.next();
continue;
}
- args.push(arg.into());
+ args.push(arg);
}
start_daemon(&alacritty, &args);
@@ -1389,24 +1379,3 @@ impl EventListener for EventProxy {
let _ = self.proxy.send_event(Event::new(event.into(), self.window_id));
}
}
-
-#[cfg(not(windows))]
-pub fn foreground_process_path() -> Result<PathBuf, Box<dyn Error>> {
- let mut pid = unsafe { libc::tcgetpgrp(tty::master_fd()) };
- if pid < 0 {
- pid = tty::child_pid();
- }
-
- #[cfg(not(any(target_os = "macos", target_os = "freebsd")))]
- let link_path = format!("/proc/{}/cwd", pid);
- #[cfg(target_os = "freebsd")]
- let link_path = format!("/compat/linux/proc/{}/cwd", pid);
-
- #[cfg(not(target_os = "macos"))]
- let cwd = std::fs::read_link(link_path)?;
-
- #[cfg(target_os = "macos")]
- let cwd = macos::proc::cwd(pid)?;
-
- Ok(cwd)
-}