diff options
author | Joe Wilm <joe@jwilm.com> | 2016-06-06 14:57:48 -0700 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2016-06-06 14:57:48 -0700 |
commit | a25c9bf1a7e2046fd89f4960aec79dffc99295db (patch) | |
tree | a468c1134d55fa212518c3da57aab32e19836e9b /src/tty.rs | |
parent | 78f5de493560b6981d7a73c35bf40b3c957bda9c (diff) | |
download | alacritty-a25c9bf1a7e2046fd89f4960aec79dffc99295db.tar.gz alacritty-a25c9bf1a7e2046fd89f4960aec79dffc99295db.zip |
Handle SIGCHLD
Closes alacritty after joining with child process.
Diffstat (limited to 'src/tty.rs')
-rw-r--r-- | src/tty.rs | 42 |
1 files changed, 36 insertions, 6 deletions
@@ -7,7 +7,32 @@ use std::mem; use std::os::unix::io::FromRawFd; use std::ptr; -use libc::{self, winsize, c_int, c_char}; +use libc::{self, winsize, c_int, c_char, pid_t, WNOHANG, WIFEXITED, WEXITSTATUS, SIGCHLD}; + +/// Process ID of child process +/// +/// Necessary to put this in static storage for `sigchld` to have access +static mut PID: pid_t = 0; + +extern "C" fn sigchld(a: c_int) { + let mut status: c_int = 0; + unsafe { + let p = libc::waitpid(PID, &mut status, WNOHANG); + if p < 0 { + die!("Waiting for pid {} failed: {}\n", PID, errno()); + } + + if PID != p { + return; + } + + if !WIFEXITED(status) || WEXITSTATUS(status) != 0 { + die!("child finished with error '{}'\n", status); + } + } + + ::std::process::exit(0); +} pub enum Error { /// TODO @@ -35,7 +60,7 @@ fn errno() -> c_int { enum Relation { Child, - Parent + Parent(pid_t) } fn fork() -> Relation { @@ -50,7 +75,7 @@ fn fork() -> Relation { if res == 0 { Relation::Child } else { - Relation::Parent + Relation::Parent(res) } } @@ -215,9 +240,15 @@ pub fn new(rows: u8, cols: u8) -> Tty { // Exec a shell! execsh(); }, - Relation::Parent => { - // Parent doesn't need slave fd + Relation::Parent(pid) => { unsafe { + // Set PID for SIGCHLD handler + PID = pid; + + // Handle SIGCHLD + libc::signal(SIGCHLD, sigchld as _); + + // Parent doesn't need slave fd libc::close(slave); } @@ -250,7 +281,6 @@ impl Tty { } pub fn resize(&self, rows: usize, cols: usize, px_x: usize, px_y: usize) { - let win = winsize { ws_row: rows as libc::c_ushort, ws_col: cols as libc::c_ushort, |