diff --git a/src/base/system.cpp b/src/base/system.cpp index 89a09f68c..d8688ac01 100644 --- a/src/base/system.cpp +++ b/src/base/system.cpp @@ -4149,18 +4149,35 @@ int kill_process(PROCESS process) { #if defined(CONF_FAMILY_WINDOWS) BOOL success = TerminateProcess(process, 0); - if(success) + BOOL is_alive = is_process_alive(process); + if(success || !is_alive) { CloseHandle(process); + return true; } - return success; + return false; #elif defined(CONF_FAMILY_UNIX) + if(!is_process_alive(process)) + return true; int status; kill(process, SIGTERM); return waitpid(process, &status, 0) != -1; #endif } +bool is_process_alive(PROCESS process) +{ + if(process == INVALID_PROCESS) + return false; +#if defined(CONF_FAMILY_WINDOWS) + DWORD exit_code; + GetExitCodeProcess(process, &exit_code); + return exit_code == STILL_ACTIVE; +#else + return waitpid(process, nullptr, WNOHANG) == 0; +#endif +} + int open_link(const char *link) { #if defined(CONF_FAMILY_WINDOWS) diff --git a/src/base/system.h b/src/base/system.h index c1f01bfe3..ef9527f84 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -2648,6 +2648,15 @@ PROCESS shell_execute(const char *file); */ int kill_process(PROCESS process); +/** + * Checks if a process is alive. + * + * @param process Handle/PID of the process. + * + * @return bool Returns true if the process is currently running, false if the process is not running (dead). + */ +bool is_process_alive(PROCESS process); + /* Function: generate_password Generates a null-terminated password of length `2 * diff --git a/src/game/client/components/menus_start.cpp b/src/game/client/components/menus_start.cpp index 791afbf06..b4fb28650 100644 --- a/src/game/client/components/menus_start.cpp +++ b/src/game/client/components/menus_start.cpp @@ -135,6 +135,10 @@ void CMenus::RenderStartMenu(CUIRect MainView) Menu.HSplitBottom(5.0f, &Menu, 0); // little space Menu.HSplitBottom(40.0f, &Menu, &Button); static CButtonContainer s_LocalServerButton; + + if(!is_process_alive(m_ServerProcess.m_Process)) + KillServer(); + if(DoButton_Menu(&s_LocalServerButton, m_ServerProcess.m_Process ? Localize("Stop server") : Localize("Run server"), 0, &Button, g_Config.m_ClShowStartMenuImages ? "local_server" : 0, IGraphics::CORNER_ALL, Rounding, 0.5f, vec4(0.0f, 0.0f, 0.0f, 0.5f), m_ServerProcess.m_Process ? vec4(0.0f, 1.0f, 0.0f, 0.25f) : vec4(0.0f, 0.0f, 0.0f, 0.25f)) || (CheckHotKey(KEY_R) && Input()->KeyPress(KEY_R))) { if(m_ServerProcess.m_Process)