automerge
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2516,6 +2516,7 @@ dependencies = [
|
|||||||
"indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -24,6 +24,7 @@ dirs = "2.0.1"
|
|||||||
indicatif = "0.11.0"
|
indicatif = "0.11.0"
|
||||||
lazy_static = "1.3.0"
|
lazy_static = "1.3.0"
|
||||||
log = "0.4.2"
|
log = "0.4.2"
|
||||||
|
nix = "0.14.1"
|
||||||
reqwest = "0.9.18"
|
reqwest = "0.9.18"
|
||||||
ring = "0.13.2"
|
ring = "0.13.2"
|
||||||
serde = "1.0.92"
|
serde = "1.0.92"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
use crate::stop_process::stop_process;
|
||||||
use crate::update_manifest::{SignedUpdateManifest, UpdateManifest};
|
use crate::update_manifest::{SignedUpdateManifest, UpdateManifest};
|
||||||
use chrono::{Local, TimeZone};
|
use chrono::{Local, TimeZone};
|
||||||
use console::{style, Emoji};
|
use console::{style, Emoji};
|
||||||
@ -793,8 +794,9 @@ pub fn run(
|
|||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
// Update successful, kill current process so it will be restart
|
// Update successful, kill current process so it will be restart
|
||||||
if let Some(ref mut child) = child_option {
|
if let Some(ref mut child) = child_option {
|
||||||
let id = child.id();
|
stop_process(child).unwrap_or_else(|err| {
|
||||||
println!("Killing pid {}: {:?}", id, child.kill());
|
eprintln!("Failed to stop child: {:?}", err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(false) => {} // No update available
|
Ok(false) => {} // No update available
|
||||||
|
@ -8,6 +8,7 @@ mod build_env;
|
|||||||
mod command;
|
mod command;
|
||||||
mod config;
|
mod config;
|
||||||
mod defaults;
|
mod defaults;
|
||||||
|
mod stop_process;
|
||||||
mod update_manifest;
|
mod update_manifest;
|
||||||
|
|
||||||
// Return an error if a url cannot be parsed.
|
// Return an error if a url cannot be parsed.
|
||||||
|
67
install/src/stop_process.rs
Normal file
67
install/src/stop_process.rs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
use std::io;
|
||||||
|
use std::process::Child;
|
||||||
|
|
||||||
|
fn kill_process(process: &mut Child) -> Result<(), io::Error> {
|
||||||
|
if let Ok(()) = process.kill() {
|
||||||
|
process.wait()?;
|
||||||
|
} else {
|
||||||
|
println!("Process {} has already exited", process.id());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub fn stop_process(process: &mut Child) -> Result<(), io::Error> {
|
||||||
|
kill_process(process)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
pub fn stop_process(process: &mut Child) -> Result<(), io::Error> {
|
||||||
|
use nix::errno::Errno::{EINVAL, EPERM, ESRCH};
|
||||||
|
use nix::sys::signal::{kill, Signal};
|
||||||
|
use nix::unistd::Pid;
|
||||||
|
use nix::Error::Sys;
|
||||||
|
use std::io::ErrorKind;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
let nice_wait = Duration::from_secs(5);
|
||||||
|
let pid = Pid::from_raw(process.id() as i32);
|
||||||
|
match kill(pid, Signal::SIGINT) {
|
||||||
|
Ok(()) => {
|
||||||
|
let expire = Instant::now() + nice_wait;
|
||||||
|
while let Ok(None) = process.try_wait() {
|
||||||
|
if Instant::now() > expire {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
thread::sleep(nice_wait / 10);
|
||||||
|
}
|
||||||
|
if let Ok(None) = process.try_wait() {
|
||||||
|
kill_process(process)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(Sys(EINVAL)) => {
|
||||||
|
println!("Invalid signal. Killing process {}", pid);
|
||||||
|
kill_process(process)?;
|
||||||
|
}
|
||||||
|
Err(Sys(EPERM)) => {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
ErrorKind::InvalidInput,
|
||||||
|
format!("Insufficient permissions to signal process {}", pid),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Err(Sys(ESRCH)) => {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
ErrorKind::InvalidInput,
|
||||||
|
format!("Process {} does not exist", pid),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
ErrorKind::InvalidInput,
|
||||||
|
format!("Unexpected error {}", e),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
Reference in New Issue
Block a user