From ff15649be77f2e66444cc98e1b1e87a20767eeef Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Fri, 21 Aug 2020 15:16:37 -0700 Subject: [PATCH] refactor: remove kill command, use libc Removes the kill command call and instead uses libc to manage killing processes. --- .vscode/settings.json | 4 ++++ src/app/data_harvester.rs | 12 +++--------- src/app/process_killer.rs | 27 +++++++++++++++++++-------- src/canvas/dialogs/dd_dialog.rs | 3 ++- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4ede05b1..905ceb81 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,12 +2,16 @@ "cSpell.words": [ "DWORD", "Deque", + "EINVAL", + "EPERM", + "ESRCH", "MSRV", "Mahmoud", "Marcin", "Nonexhaustive", "PKGBUILD", "Qudsi", + "SIGTERM", "Tebibytes", "Ungrouped", "WASD", diff --git a/src/app/data_harvester.rs b/src/app/data_harvester.rs index 042638b0..7b5f9d0a 100644 --- a/src/app/data_harvester.rs +++ b/src/app/data_harvester.rs @@ -87,6 +87,7 @@ pub struct DataCollector { widgets_to_harvest: UsedWidgets, battery_manager: Option, battery_list: Option>, + #[cfg(target_os = "linux")] page_file_size_kb: u64, } @@ -111,15 +112,8 @@ impl Default for DataCollector { widgets_to_harvest: UsedWidgets::default(), battery_manager: None, battery_list: None, - page_file_size_kb: { - #[cfg(target_os = "linux")] - unsafe { - libc::sysconf(libc::_SC_PAGESIZE) as u64 / 1024 - } - - #[cfg(not(target_os = "linux"))] - 0 - }, + #[cfg(target_os = "linux")] + page_file_size_kb: unsafe { libc::sysconf(libc::_SC_PAGESIZE) as u64 / 1024 }, } } } diff --git a/src/app/process_killer.rs b/src/app/process_killer.rs index 68754c39..ac18742d 100644 --- a/src/app/process_killer.rs +++ b/src/app/process_killer.rs @@ -1,5 +1,3 @@ -use std::process::Command; - // Copied from SO: https://stackoverflow.com/a/55231715 #[cfg(target_os = "windows")] use winapi::{ @@ -35,12 +33,25 @@ impl Process { /// Kills a process, given a PID. pub fn kill_process_given_pid(pid: u32) -> crate::utils::error::Result<()> { if cfg!(target_os = "linux") || cfg!(target_os = "macos") { - // FIXME: Use libc instead of a command... - let output = Command::new("kill").arg(pid.to_string()).output()?; - if !(output.status).success() { - return Err(BottomError::GenericError( - std::str::from_utf8(&output.stderr)?.to_string(), - )); + #[cfg(any(target_os = "linux", target_os = "macos"))] + { + let output = unsafe { libc::kill(pid as i32, libc::SIGTERM) }; + if output != 0 { + // We had an error... + let err_code = std::io::Error::last_os_error().raw_os_error(); + let err = match err_code { + Some(libc::ESRCH) => "the target process did not exist.", + Some(libc::EPERM) => "the calling process does not have the permissions to terminate the target process(es).", + Some(libc::EINVAL) => "an invalid signal was specified.", + _ => "Unknown error occurred." + }; + + return Err(BottomError::GenericError(format!( + "Error code {} - {}", + err_code.unwrap_or(-1), + err, + ))); + } } } else if cfg!(target_os = "windows") { #[cfg(target_os = "windows")] diff --git a/src/canvas/dialogs/dd_dialog.rs b/src/canvas/dialogs/dd_dialog.rs index 8b3f342c..4d09b504 100644 --- a/src/canvas/dialogs/dd_dialog.rs +++ b/src/canvas/dialogs/dd_dialog.rs @@ -24,7 +24,8 @@ impl KillDialog for Painter { if let Some(dd_err) = &app_state.dd_err { return Some(vec![ Text::raw("\n"), - Text::raw(format!("Failure to properly kill the process - {}", dd_err)), + Text::raw(format!("Failed to kill process.\n{}\n", dd_err)), + Text::raw("Please press ENTER or ESC to close this dialog."), ]); } else if let Some(to_kill_processes) = app_state.get_to_delete_processes() { if let Some(first_pid) = to_kill_processes.1.first() {