diff options
author | Mattbazooka <mattbazooka@gmail.com> | 2020-07-14 19:03:36 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-14 09:03:36 +0000 |
commit | 76a4c373da48a4477c07b844442e5599fbd37ada (patch) | |
tree | 5af50d7a034c3c030a1a2c19e81e21bcd66c43d1 | |
parent | 68209e88fd8c8b092785aaadfaea8ef7d4a4e2cf (diff) | |
download | alacritty-76a4c373da48a4477c07b844442e5599fbd37ada.tar.gz alacritty-76a4c373da48a4477c07b844442e5599fbd37ada.zip |
Fallback to SHELL instead of passwd if present
Instead of just always falling back to the shell specified in the passwd
file when no config or cli shell was specified, Alacritty will not first
look at the `$SHELL` environment variable. If this is unset, it will
still read the passwd file.
Since macOS is a bit peculiar and does not set the `$SHELL` environment
variable by default, it is set manually to the shell used by Alacritty
while any existing `$SHELL` variables are ignored. This matches the
behavior of iTerm and Terminal.app.
Co-authored-by: Christian Duerr <contact@christianduerr.com>
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | alacritty_terminal/src/tty/unix.rs | 66 |
2 files changed, 40 insertions, 27 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index f1cea655..e773d4e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for `gopher` and `gemini` URLs - Unicode 13 support - Option to run command on bell which can be set in `bell.command` +- Fallback to program specified in `$SHELL` variable on Linux/BSD if it is present ### Changed diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs index b6807cc2..b373ada2 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -1,18 +1,7 @@ //! TTY related functionality. -use crate::config::{Config, Program}; -use crate::event::OnResize; -use crate::term::SizeInfo; -use crate::tty::{ChildEvent, EventedPty, EventedReadWrite}; - -use libc::{self, c_int, pid_t, winsize, TIOCSCTTY}; -use log::error; -use nix::pty::openpty; -#[cfg(any(target_os = "linux", target_os = "macos"))] -use nix::sys::termios::{self, InputFlags, SetArg}; -use signal_hook::{self as sighook, iterator::Signals}; - -use mio::unix::EventedFd; +use std::borrow::Cow; +use std::env; use std::ffi::CStr; use std::fs::File; use std::io; @@ -25,6 +14,19 @@ use std::process::{Child, Command, Stdio}; use std::ptr; use std::sync::atomic::{AtomicUsize, Ordering}; +use libc::{self, c_int, pid_t, winsize, TIOCSCTTY}; +use log::error; +use mio::unix::EventedFd; +use nix::pty::openpty; +#[cfg(any(target_os = "linux", target_os = "macos"))] +use nix::sys::termios::{self, InputFlags, SetArg}; +use signal_hook::{self as sighook, iterator::Signals}; + +use crate::config::{Config, Program}; +use crate::event::OnResize; +use crate::term::SizeInfo; +use crate::tty::{ChildEvent, EventedPty, EventedReadWrite}; + /// Process ID of child process. /// /// Necessary to put this in static storage for `SIGCHLD` to have access. @@ -128,13 +130,22 @@ pub struct Pty { signals_token: mio::Token, } +#[cfg(target_os = "macos")] +fn default_shell(pw: &Passwd<'_>) -> Program { + let shell_name = pw.shell.rsplit('/').next().unwrap(); + let argv = vec![String::from("-c"), format!("exec -a -{} {}", shell_name, pw.shell)]; + + Program::WithArgs { program: "/bin/bash".to_owned(), args: argv } +} + +#[cfg(not(target_os = "macos"))] +fn default_shell(pw: &Passwd<'_>) -> Program { + Program::Just(env::var("SHELL").unwrap_or_else(|_| pw.shell.to_owned())) +} + /// Create a new TTY and return a handle to interact with it. pub fn new<C>(config: &Config<C>, size: &SizeInfo, window_id: Option<usize>) -> Pty { - let win_size = size.to_winsize(); - let mut buf = [0; 1024]; - let pw = get_pw_entry(&mut buf); - - let (master, slave) = make_pty(win_size); + let (master, slave) = make_pty(size.to_winsize()); #[cfg(any(target_os = "linux", target_os = "macos"))] { @@ -145,17 +156,15 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, window_id: Option<usize>) -> } } - let default_shell = if cfg!(target_os = "macos") { - let shell_name = pw.shell.rsplit('/').next().unwrap(); - let argv = vec![String::from("-c"), format!("exec -a -{} {}", shell_name, pw.shell)]; + let mut buf = [0; 1024]; + let pw = get_pw_entry(&mut buf); - Program::WithArgs { program: "/bin/bash".to_owned(), args: argv } - } else { - Program::Just(pw.shell.to_owned()) + let shell = match config.shell.as_ref() { + Some(shell) => Cow::Borrowed(shell), + None => Cow::Owned(default_shell(&pw)), }; - let shell = config.shell.as_ref().unwrap_or(&default_shell); - let mut builder = Command::new(&*shell.program()); + let mut builder = Command::new(shell.program()); for arg in shell.args() { builder.arg(arg); } @@ -171,9 +180,12 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, window_id: Option<usize>) -> // Setup shell environment. builder.env("LOGNAME", pw.name); builder.env("USER", pw.name); - builder.env("SHELL", pw.shell); builder.env("HOME", pw.dir); + // Set $SHELL environment variable on macOS, since login does not do it for us. + #[cfg(target_os = "macos")] + builder.env("SHELL", config.shell.as_ref().map(|sh| sh.program()).unwrap_or(pw.shell)); + if let Some(window_id) = window_id { builder.env("WINDOWID", format!("{}", window_id)); } |