aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/tty/unix.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal/src/tty/unix.rs')
-rw-r--r--alacritty_terminal/src/tty/unix.rs34
1 files changed, 18 insertions, 16 deletions
diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs
index 54118a58..8084a753 100644
--- a/alacritty_terminal/src/tty/unix.rs
+++ b/alacritty_terminal/src/tty/unix.rs
@@ -5,10 +5,10 @@ use std::fs::File;
use std::io::{Error, ErrorKind, Read, Result};
use std::mem::MaybeUninit;
use std::os::fd::OwnedFd;
-use std::os::unix::io::{AsRawFd, FromRawFd};
+use std::os::unix::io::AsRawFd;
use std::os::unix::net::UnixStream;
use std::os::unix::process::CommandExt;
-use std::process::{Child, Command, Stdio};
+use std::process::{Child, Command};
use std::sync::Arc;
use std::{env, ptr};
@@ -19,8 +19,8 @@ use rustix_openpty::openpty;
use rustix_openpty::rustix::termios::Winsize;
#[cfg(any(target_os = "linux", target_os = "macos"))]
use rustix_openpty::rustix::termios::{self, InputModes, OptionalActions};
-use signal_hook::consts as sigconsts;
-use signal_hook::low_level::pipe as signal_pipe;
+use signal_hook::low_level::{pipe as signal_pipe, unregister as unregister_signal};
+use signal_hook::{consts as sigconsts, SigId};
use crate::event::{OnResize, WindowSize};
use crate::tty::{ChildEvent, EventedPty, EventedReadWrite, Options};
@@ -102,6 +102,7 @@ pub struct Pty {
child: Child,
file: File,
signals: UnixStream,
+ sig_id: SigId,
}
impl Pty {
@@ -123,7 +124,7 @@ struct ShellUser {
impl ShellUser {
/// look for shell, username, longname, and home dir in the respective environment variables
- /// before falling back on looking in to `passwd`.
+ /// before falling back on looking into `passwd`.
fn from_env() -> Result<Self> {
let mut buf = [0; 1024];
let pw = get_pw_entry(&mut buf);
@@ -177,7 +178,7 @@ fn default_shell_command(shell: &str, user: &str) -> Command {
// -p: Preserves the environment.
//
// XXX: we use zsh here over sh due to `exec -a`.
- login_command.args(["-flp", user, "/bin/zsh", "-c", &exec]);
+ login_command.args(["-flp", user, "/bin/zsh", "-fc", &exec]);
login_command
}
@@ -211,12 +212,9 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd
};
// Setup child stdin/stdout/stderr as slave fd of PTY.
- // Ownership of fd is transferred to the Stdio structs and will be closed by them at the end of
- // this scope. (It is not an issue that the fd is closed three times since File::drop ignores
- // error on libc::close.).
- builder.stdin(unsafe { Stdio::from_raw_fd(slave_fd) });
- builder.stderr(unsafe { Stdio::from_raw_fd(slave_fd) });
- builder.stdout(unsafe { Stdio::from_raw_fd(slave_fd) });
+ builder.stdin(slave.try_clone()?);
+ builder.stderr(slave.try_clone()?);
+ builder.stdout(slave);
// Setup shell environment.
let window_id = window_id.to_string();
@@ -260,13 +258,13 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd
}
// Prepare signal handling before spawning child.
- let signals = {
+ let (signals, sig_id) = {
let (sender, recv) = UnixStream::pair()?;
// Register the recv end of the pipe for SIGCHLD.
- signal_pipe::register(sigconsts::SIGCHLD, sender)?;
+ let sig_id = signal_pipe::register(sigconsts::SIGCHLD, sender)?;
recv.set_nonblocking(true)?;
- recv
+ (recv, sig_id)
};
match builder.spawn() {
@@ -277,7 +275,7 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd
set_nonblocking(master_fd);
}
- Ok(Pty { child, file: File::from(master), signals })
+ Ok(Pty { child, file: File::from(master), signals, sig_id })
},
Err(err) => Err(Error::new(
err.kind(),
@@ -296,6 +294,10 @@ impl Drop for Pty {
unsafe {
libc::kill(self.child.id() as i32, libc::SIGHUP);
}
+
+ // Clear signal-hook handler.
+ unregister_signal(self.sig_id);
+
let _ = self.child.wait();
}
}