summaryrefslogtreecommitdiffstats
path: root/alacritty_terminal
diff options
context:
space:
mode:
authorMattbazooka <mattbazooka@gmail.com>2020-07-14 19:03:36 +1000
committerGitHub <noreply@github.com>2020-07-14 09:03:36 +0000
commit76a4c373da48a4477c07b844442e5599fbd37ada (patch)
tree5af50d7a034c3c030a1a2c19e81e21bcd66c43d1 /alacritty_terminal
parent68209e88fd8c8b092785aaadfaea8ef7d4a4e2cf (diff)
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>
Diffstat (limited to 'alacritty_terminal')
-rw-r--r--alacritty_terminal/src/tty/unix.rs66
1 files changed, 39 insertions, 27 deletions
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));
}