diff --git a/src/common/platform/posix/cocoa/i_main.mm b/src/common/platform/posix/cocoa/i_main.mm index 10f3a60ab..78ad7b7cf 100644 --- a/src/common/platform/posix/cocoa/i_main.mm +++ b/src/common/platform/posix/cocoa/i_main.mm @@ -3,6 +3,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 2012-2018 Alexey Lysiuk + ** Copyright 2017-2025 GZDoom Maintainers and Contributors ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -36,6 +37,7 @@ #include #include +#include #include "c_console.h" #include "c_cvars.h" @@ -61,6 +63,8 @@ EXTERN_CVAR(Int, vid_defheight) EXTERN_CVAR(Bool, vid_vsync ) int GameMain(); +void SignalHandler(int signal); + // --------------------------------------------------------------------------- @@ -209,6 +213,11 @@ TArray s_argv; int DoMain(int argc, char** argv) { + signal(SIGINT, SignalHandler); + signal(SIGTERM, SignalHandler); + // signal(SIGHUP, SignalHandler); + // signal(SIGQUIT, SignalHandler); + printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n\n", GetVersionString(), GetGitTime(), __DATE__); diff --git a/src/common/platform/posix/sdl/i_main.cpp b/src/common/platform/posix/sdl/i_main.cpp index 2ecc14686..a8ee3bf80 100644 --- a/src/common/platform/posix/sdl/i_main.cpp +++ b/src/common/platform/posix/sdl/i_main.cpp @@ -4,6 +4,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 1998-2007 Randy Heit +** Copyright 2017-2025 GZDoom Maintainers and Contributors ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -42,6 +43,7 @@ #include #include #include +#include #include "engineerrors.h" #include "m_argv.h" @@ -71,6 +73,7 @@ void Linux_I_FatalError(const char* errortext); // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- int GameMain(); +void SignalHandler(int signal); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- @@ -155,6 +158,11 @@ int main (int argc, char **argv) } #endif // !__APPLE__ + signal(SIGINT, SignalHandler); + signal(SIGTERM, SignalHandler); + // signal(SIGHUP, SignalHandler); + // signal(SIGQUIT, SignalHandler); + printf(GAMENAME" %s - %s - SDL version\nCompiled on %s\n", GetVersionString(), GetGitTime(), __DATE__); diff --git a/src/common/platform/posix/sdl/st_start.cpp b/src/common/platform/posix/sdl/st_start.cpp index 65b1d2cf1..e9d2de706 100644 --- a/src/common/platform/posix/sdl/st_start.cpp +++ b/src/common/platform/posix/sdl/st_start.cpp @@ -80,6 +80,7 @@ class FTTYStartupScreen : public FStartupScreen extern void RedrawProgressBar(int CurPos, int MaxPos); extern void CleanProgressBar(); +extern volatile sig_atomic_t gameloop_abort; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -269,12 +270,6 @@ int FTTYStartupScreen::GetNetBanClient() return -1; } -static volatile sig_atomic_t netloop_running; -void netloop_handler(int signal) -{ - netloop_running = false; -} - //=========================================================================== // // FTTYStartupScreen :: NetLoop @@ -297,10 +292,7 @@ bool FTTYStartupScreen::NetLoop(bool (*loopCallback)(void *), void *data) char k; bool stdin_eof = false; - netloop_running = true; - auto previous_handler = std::signal(SIGINT, netloop_handler); - - while (netloop_running) + while (!gameloop_abort) { // Don't flood the network with packets on startup. tv.tv_sec = 0; @@ -338,15 +330,13 @@ bool FTTYStartupScreen::NetLoop(bool (*loopCallback)(void *), void *data) { if (k == 'q' || k == 'Q') { - netloop_running = false; + break; } } } } - std::signal(SIGINT, previous_handler); - - fprintf (stderr, "\nNetwork game synchronization aborted."); + fprintf (stderr, "\nNetwork game synchronization aborted.\n"); return false; } diff --git a/src/common/platform/win32/i_main.cpp b/src/common/platform/win32/i_main.cpp index ce166b8db..48a0d0858 100644 --- a/src/common/platform/win32/i_main.cpp +++ b/src/common/platform/win32/i_main.cpp @@ -4,6 +4,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 1998-2009 Randy Heit +** Copyright 2017-2025 GZDoom Maintainers and Contributors ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -40,6 +41,7 @@ #include #include #include +#include #include #include @@ -100,6 +102,7 @@ void CreateCrashLog (const char *custominfo, DWORD customsize); void DisplayCrashLog (); void DestroyCustomCursor(); int GameMain(); +void SignalHandler(int signal); // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -181,6 +184,11 @@ int DoMain (HINSTANCE hInstance) TIMECAPS tc; DEVMODE displaysettings; + signal(SIGINT, SignalHandler); + signal(SIGTERM, SignalHandler); + // signal(SIGHUP, SignalHandler); + // signal(SIGQUIT, SignalHandler); + // Do not use the multibyte __argv here because we want UTF-8 arguments // and those can only be done by converting the Unicode variants. Args = new FArgs(); diff --git a/src/d_main.cpp b/src/d_main.cpp index 1505f880e..6f85fb062 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -329,6 +329,7 @@ FString lastIWAD; int restart = 0; extern bool AppActive; bool playedtitlemusic; +volatile sig_atomic_t gameloop_abort = false; FStartScreen* StartScreen; std::unique_ptr debugServer; @@ -1259,6 +1260,12 @@ void D_DoomLoop () D_ProcessEvents(); D_Display (); S_UpdateMusic(); + + if (gameloop_abort) + { + C_DoCommand("quickexit"); + } + if (wantToRestart) { wantToRestart = false; @@ -3739,7 +3746,6 @@ static int D_DoomMain_Internal (void) RemapUserTranslation }; - std::set_new_handler(NewFailure); const char *batchout = Args->CheckValue("-errorlog"); @@ -3879,6 +3885,20 @@ static int D_DoomMain_Internal (void) while (1); } +void SignalHandler(int signal) +{ + if (gameloop_abort) + { + Printf("Received signal %d, exiting\n", signal); + exit(0); + } + else + { + Printf("Received signal %d, shutting down\n", signal); + gameloop_abort = true; + } +} + int GameMain() { // On Windows, prefer the native win32 backend. diff --git a/src/d_main.h b/src/d_main.h index 33720fc33..e31b3e61d 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -3,6 +3,7 @@ // Copyright 1993-1996 id Software // Copyright 1999-2016 Randy Heit // Copyright 2002-2016 Christoph Oelckers +// Copyright 2017-2025 GZDoom Maintainers and Contributors // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -32,8 +33,10 @@ #include "gametype.h" #include "startupinfo.h" #include "c_cvars.h" +#include extern bool advancedemo; +extern volatile sig_atomic_t gameloop_abort; EXTERN_CVAR(Bool, hud_toggled); void D_ToggleHud(); diff --git a/src/menu/doommenu.cpp b/src/menu/doommenu.cpp index 43adc082e..27d2646fa 100644 --- a/src/menu/doommenu.cpp +++ b/src/menu/doommenu.cpp @@ -4,6 +4,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 2010 Christoph Oelckers +** Copyright 2017-2025 GZDoom Maintainers and Contributors ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -375,6 +376,17 @@ static void M_Quit() // //============================================================================= +CCMD (quickexit) +{ + M_Quit(); +} + +//============================================================================= +// +// +// +//============================================================================= + CCMD (menu_quit) { // F10 if (m_quickexit)