mirror of
https://github.com/alacritty/alacritty.git
synced 2025-02-10 15:46:10 -05:00
Detach Child process to avoid zombie processes
This makes use of the common double-fork behavior to prevent spawning zombie processes every time a URL is clicked.
This commit is contained in:
parent
f57bd6e12f
commit
cadbb86eb7
3 changed files with 34 additions and 39 deletions
|
@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
- Fixed a bad type conversion which could cause underflow on a window resize
|
- Fixed a bad type conversion which could cause underflow on a window resize
|
||||||
- Alacritty now spawns a login shell on macOS, as with Terminal.app and iTerm2
|
- Alacritty now spawns a login shell on macOS, as with Terminal.app and iTerm2
|
||||||
|
- Fixed zombie processes sticking around after launching URLs
|
||||||
|
|
||||||
## Version 0.2.3
|
## Version 0.2.3
|
||||||
|
|
||||||
|
|
29
src/input.rs
29
src/input.rs
|
@ -20,10 +20,7 @@
|
||||||
//! determine what to do when a non-modifier key is pressed.
|
//! determine what to do when a non-modifier key is pressed.
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::process::Command;
|
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
#[cfg(not(windows))]
|
|
||||||
use std::os::unix::process::CommandExt;
|
|
||||||
|
|
||||||
use copypasta::{Clipboard, Load, Buffer as ClipboardBuffer};
|
use copypasta::{Clipboard, Load, Buffer as ClipboardBuffer};
|
||||||
use glutin::{ElementState, MouseButton, TouchPhase, MouseScrollDelta, ModifiersState, KeyboardInput};
|
use glutin::{ElementState, MouseButton, TouchPhase, MouseScrollDelta, ModifiersState, KeyboardInput};
|
||||||
|
@ -35,6 +32,7 @@ use index::{Line, Column, Side, Point};
|
||||||
use term::SizeInfo;
|
use term::SizeInfo;
|
||||||
use term::mode::TermMode;
|
use term::mode::TermMode;
|
||||||
use util::fmt::Red;
|
use util::fmt::Red;
|
||||||
|
use util::start_daemon;
|
||||||
|
|
||||||
pub const FONT_SIZE_STEP: f32 = 0.5;
|
pub const FONT_SIZE_STEP: f32 = 0.5;
|
||||||
|
|
||||||
|
@ -239,26 +237,9 @@ impl Action {
|
||||||
Action::Command(ref program, ref args) => {
|
Action::Command(ref program, ref args) => {
|
||||||
trace!("running command: {} {:?}", program, args);
|
trace!("running command: {} {:?}", program, args);
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
match start_daemon(program, args) {
|
||||||
let spawned = Command::new(program)
|
Ok(_) => {
|
||||||
.args(args)
|
debug!("spawned new proc");
|
||||||
.before_exec(|| {
|
|
||||||
// Detach forked process from Alacritty. This will cause
|
|
||||||
// init or whatever to clean up child processes for us.
|
|
||||||
unsafe { ::libc::daemon(1, 0); }
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
.spawn();
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
let spawned = Command::new(program)
|
|
||||||
.args(args)
|
|
||||||
.spawn();
|
|
||||||
|
|
||||||
match spawned
|
|
||||||
{
|
|
||||||
Ok(child) => {
|
|
||||||
debug!("spawned new proc with pid: {}", child.id());
|
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("couldn't run command: {}", err);
|
warn!("couldn't run command: {}", err);
|
||||||
|
@ -557,7 +538,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
let mut args = launcher.args().to_vec();
|
let mut args = launcher.args().to_vec();
|
||||||
args.push(text);
|
args.push(text);
|
||||||
|
|
||||||
match Command::new(launcher.program()).args(&args).spawn() {
|
match start_daemon(launcher.program(), &args) {
|
||||||
Ok(_) => debug!("Launched: {} {:?}", launcher.program(), args),
|
Ok(_) => debug!("Launched: {} {:?}", launcher.program(), args),
|
||||||
Err(_) => warn!("Unable to launch: {} {:?}", launcher.program(), args),
|
Err(_) => warn!("Unable to launch: {} {:?}", launcher.program(), args),
|
||||||
}
|
}
|
||||||
|
|
43
src/util.rs
43
src/util.rs
|
@ -11,25 +11,20 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use std::cmp;
|
#[cfg(not(windows))]
|
||||||
|
use std::os::unix::process::CommandExt;
|
||||||
#[cfg(not(feature = "nightly"))]
|
use std::process::Command;
|
||||||
#[inline(always)]
|
use std::{cmp, io};
|
||||||
pub unsafe fn unlikely(x: bool) -> bool {
|
|
||||||
x
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
|
||||||
pub use ::std::intrinsics::unlikely;
|
|
||||||
|
|
||||||
/// Threading utilities
|
/// Threading utilities
|
||||||
pub mod thread {
|
pub mod thread {
|
||||||
/// Like `thread::spawn`, but with a `name` argument
|
/// Like `thread::spawn`, but with a `name` argument
|
||||||
pub fn spawn_named<F, T, S>(name: S, f: F) -> ::std::thread::JoinHandle<T>
|
pub fn spawn_named<F, T, S>(name: S, f: F) -> ::std::thread::JoinHandle<T>
|
||||||
where F: FnOnce() -> T,
|
where
|
||||||
F: Send + 'static,
|
F: FnOnce() -> T,
|
||||||
T: Send + 'static,
|
F: Send + 'static,
|
||||||
S: Into<String>
|
T: Send + 'static,
|
||||||
|
S: Into<String>,
|
||||||
{
|
{
|
||||||
::std::thread::Builder::new()
|
::std::thread::Builder::new()
|
||||||
.name(name.into())
|
.name(name.into())
|
||||||
|
@ -37,7 +32,7 @@ pub mod thread {
|
||||||
.expect("thread spawn works")
|
.expect("thread spawn works")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use ::std::thread::*;
|
pub use std::thread::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn limit<T: Ord>(value: T, min: T, max: T) -> T {
|
pub fn limit<T: Ord>(value: T, min: T, max: T) -> T {
|
||||||
|
@ -81,6 +76,24 @@ pub mod fmt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
pub fn start_daemon(program: &str, args: &[String]) -> io::Result<()> {
|
||||||
|
Command::new(program)
|
||||||
|
.args(args)
|
||||||
|
.before_exec(|| unsafe {
|
||||||
|
::libc::daemon(1, 0);
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.spawn()?
|
||||||
|
.wait()
|
||||||
|
.map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub fn start_daemon(program: &str, args: &[String]) -> io::Result<()> {
|
||||||
|
Command::new(program).args(args).spawn().map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::limit;
|
use super::limit;
|
||||||
|
|
Loading…
Add table
Reference in a new issue