diff --git a/src/main.rs b/src/main.rs index 370aaa8..64d4a4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ pub(crate) mod cli; pub(crate) mod config; pub(crate) mod mc; pub(crate) mod monitor; +pub(crate) mod os; pub(crate) mod proto; pub(crate) mod proxy; pub(crate) mod server; diff --git a/src/os/mod.rs b/src/os/mod.rs new file mode 100644 index 0000000..523880c --- /dev/null +++ b/src/os/mod.rs @@ -0,0 +1,20 @@ +#[cfg(unix)] +pub mod unix; + +/// Gracefully kill process. +/// +/// # Panics +/// +/// Panics on platforms other than Unix. +#[allow(unreachable_code)] +pub fn kill_gracefully(pid: u32) { + #[cfg(unix)] + unsafe { + unix::kill_gracefully(pid); + return; + } + + unimplemented!( + "gracefully killing Minecraft server process not implemented on non-Unix platforms" + ); +} diff --git a/src/os/unix.rs b/src/os/unix.rs new file mode 100644 index 0000000..c44b4a8 --- /dev/null +++ b/src/os/unix.rs @@ -0,0 +1,11 @@ +/// Gracefully kill process on Unix by sending SIGTERM. +/// +/// This is unsafe because the PID isn't checked. +pub unsafe fn kill_gracefully(pid: u32) { + debug!(target: "lazymc", "Sending SIGTERM signal to {} to kill server", pid); + let result = libc::kill(pid as i32, libc::SIGTERM); + trace!(target: "lazymc", "SIGTERM result: {}", result); + + // TODO: send sigterm to childs as well? + // TODO: handle error if result != 0 +} diff --git a/src/server.rs b/src/server.rs index 13316cc..de113f7 100644 --- a/src/server.rs +++ b/src/server.rs @@ -64,7 +64,7 @@ impl ServerState { pub fn kill_server(&self) -> bool { if let Some(pid) = *self.pid.lock().unwrap() { debug!(target: "lazymc", "Sending kill signal to server"); - kill_gracefully(pid); + crate::os::unix::kill_gracefully(pid); // TODO: should we set this? self.set_online(false);