1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Avoid signal-unsafe operations in POSIX signal handler (#16160)

This commit is contained in:
JosiahWI 2025-06-01 08:24:32 -05:00 committed by GitHub
parent 56a7f0b7cf
commit 0bb87eb1ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 53 additions and 42 deletions

View file

@ -147,8 +147,8 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
/* /*
Menu-game loop Menu-game loop
*/ */
bool retval = true; bool retval = true;
bool *kill = porting::signal_handler_killstatus(); volatile auto *kill = porting::signal_handler_killstatus();
while (m_rendering_engine->run() && !*kill && while (m_rendering_engine->run() && !*kill &&
!g_gamecallback->shutdown_requested) { !g_gamecallback->shutdown_requested) {
@ -540,9 +540,9 @@ bool ClientLauncher::launch_game(std::string &error_message,
void ClientLauncher::main_menu(MainMenuData *menudata) void ClientLauncher::main_menu(MainMenuData *menudata)
{ {
bool *kill = porting::signal_handler_killstatus(); volatile auto *kill = porting::signal_handler_killstatus();
video::IVideoDriver *driver = m_rendering_engine->get_video_driver(); video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
auto *device = m_rendering_engine->get_raw_device(); auto *device = m_rendering_engine->get_raw_device();
// Wait until app is in foreground because of #15883 // Wait until app is in foreground because of #15883
infostream << "Waiting for app to be in foreground" << std::endl; infostream << "Waiting for app to be in foreground" << std::endl;

View file

@ -65,6 +65,8 @@
#include "client/sound/sound_openal.h" #include "client/sound/sound_openal.h"
#endif #endif
#include <csignal>
class NodeDugEvent : public MtEvent class NodeDugEvent : public MtEvent
{ {
public: public:
@ -561,7 +563,7 @@ public:
Game(); Game();
~Game(); ~Game();
bool startup(bool *kill, bool startup(volatile std::sig_atomic_t *kill,
InputHandler *input, InputHandler *input,
RenderingEngine *rendering_engine, RenderingEngine *rendering_engine,
const GameStartData &game_params, const GameStartData &game_params,
@ -793,14 +795,14 @@ private:
This class does take ownership/responsibily for cleaning up etc of any of This class does take ownership/responsibily for cleaning up etc of any of
these items (e.g. device) these items (e.g. device)
*/ */
IrrlichtDevice *device; IrrlichtDevice *device;
RenderingEngine *m_rendering_engine; RenderingEngine *m_rendering_engine;
video::IVideoDriver *driver; video::IVideoDriver *driver;
scene::ISceneManager *smgr; scene::ISceneManager *smgr;
bool *kill; volatile std::sig_atomic_t *kill;
std::string *error_message; std::string *error_message;
bool *reconnect_requested; bool *reconnect_requested;
PausedNodesList paused_animated_nodes; PausedNodesList paused_animated_nodes;
bool simple_singleplayer_mode; bool simple_singleplayer_mode;
/* End 'cache' */ /* End 'cache' */
@ -932,7 +934,7 @@ Game::~Game()
m_rendering_engine->finalize(); m_rendering_engine->finalize();
} }
bool Game::startup(bool *kill, bool Game::startup(volatile std::sig_atomic_t *kill,
InputHandler *input, InputHandler *input,
RenderingEngine *rendering_engine, RenderingEngine *rendering_engine,
const GameStartData &start_data, const GameStartData &start_data,
@ -4235,7 +4237,7 @@ void Game::readSettings()
****************************************************************************/ ****************************************************************************/
/****************************************************************************/ /****************************************************************************/
void the_game(bool *kill, void the_game(volatile std::sig_atomic_t *kill,
InputHandler *input, InputHandler *input,
RenderingEngine *rendering_engine, RenderingEngine *rendering_engine,
const GameStartData &start_data, const GameStartData &start_data,

View file

@ -6,6 +6,7 @@
#include "irrlichttypes.h" #include "irrlichttypes.h"
#include "config.h" #include "config.h"
#include <csignal>
#include <string> #include <string>
#if !IS_CLIENT_BUILD #if !IS_CLIENT_BUILD
@ -36,7 +37,7 @@ struct CameraOrientation {
#define GAME_FALLBACK_TIMEOUT 1.8f #define GAME_FALLBACK_TIMEOUT 1.8f
#define GAME_CONNECTION_TIMEOUT 10.0f #define GAME_CONNECTION_TIMEOUT 10.0f
void the_game(bool *kill, void the_game(volatile std::sig_atomic_t *kill,
InputHandler *input, InputHandler *input,
RenderingEngine *rendering_engine, RenderingEngine *rendering_engine,
const GameStartData &start_data, const GameStartData &start_data,

View file

@ -33,6 +33,8 @@
#include "client/sound/sound_openal.h" #include "client/sound/sound_openal.h"
#endif #endif
#include <csignal>
/******************************************************************************/ /******************************************************************************/
void TextDestGuiEngine::gotText(const StringMap &fields) void TextDestGuiEngine::gotText(const StringMap &fields)
@ -104,7 +106,7 @@ GUIEngine::GUIEngine(JoystickController *joystick,
RenderingEngine *rendering_engine, RenderingEngine *rendering_engine,
IMenuManager *menumgr, IMenuManager *menumgr,
MainMenuData *data, MainMenuData *data,
bool &kill) : volatile std::sig_atomic_t &kill) :
m_rendering_engine(rendering_engine), m_rendering_engine(rendering_engine),
m_parent(parent), m_parent(parent),
m_menumanager(menumgr), m_menumanager(menumgr),

View file

@ -14,6 +14,8 @@
#include "util/enriched_string.h" #include "util/enriched_string.h"
#include "translation.h" #include "translation.h"
#include <csignal>
/******************************************************************************/ /******************************************************************************/
/* Structs and macros */ /* Structs and macros */
/******************************************************************************/ /******************************************************************************/
@ -124,7 +126,7 @@ public:
RenderingEngine *rendering_engine, RenderingEngine *rendering_engine,
IMenuManager *menumgr, IMenuManager *menumgr,
MainMenuData *data, MainMenuData *data,
bool &kill); volatile std::sig_atomic_t &kill);
/** default destructor */ /** default destructor */
virtual ~GUIEngine(); virtual ~GUIEngine();
@ -193,7 +195,7 @@ private:
irr_ptr<GUIFormSpecMenu> m_menu; irr_ptr<GUIFormSpecMenu> m_menu;
/** reference to kill variable managed by SIGINT handler */ /** reference to kill variable managed by SIGINT handler */
bool &m_kill; volatile std::sig_atomic_t &m_kill;
/** variable used to abort menu and return back to main game handling */ /** variable used to abort menu and return back to main game handling */
bool m_startgame = false; bool m_startgame = false;

View file

@ -1138,7 +1138,7 @@ static bool run_dedicated_server(const GameParams &game_params, const Settings &
return false; return false;
} }
ChatInterface iface; ChatInterface iface;
bool &kill = *porting::signal_handler_killstatus(); volatile auto &kill = *porting::signal_handler_killstatus();
try { try {
// Create server // Create server
@ -1181,7 +1181,7 @@ static bool run_dedicated_server(const GameParams &game_params, const Settings &
server.start(); server.start();
// Run server // Run server
bool &kill = *porting::signal_handler_killstatus(); volatile auto &kill = *porting::signal_handler_killstatus();
dedicated_server_loop(server, kill); dedicated_server_loop(server, kill);
} catch (const ModError &e) { } catch (const ModError &e) {
@ -1226,7 +1226,7 @@ static bool migrate_map_database(const GameParams &game_params, const Settings &
u32 count = 0; u32 count = 0;
u64 last_update_time = 0; u64 last_update_time = 0;
bool &kill = *porting::signal_handler_killstatus(); volatile auto &kill = *porting::signal_handler_killstatus();
std::vector<v3s16> blocks; std::vector<v3s16> blocks;
old_db->listAllLoadableBlocks(blocks); old_db->listAllLoadableBlocks(blocks);
@ -1280,7 +1280,7 @@ static bool recompress_map_database(const GameParams &game_params, const Setting
u32 count = 0; u32 count = 0;
u64 last_update_time = 0; u64 last_update_time = 0;
bool &kill = *porting::signal_handler_killstatus(); volatile auto &kill = *porting::signal_handler_killstatus();
const u8 serialize_as_ver = SER_FMT_VER_HIGHEST_WRITE; const u8 serialize_as_ver = SER_FMT_VER_HIGHEST_WRITE;
const s16 map_compression_level = rangelim(g_settings->getS16("map_compression_level_disk"), -1, 9); const s16 map_compression_level = rangelim(g_settings->getS16("map_compression_level_disk"), -1, 9);

View file

@ -60,6 +60,7 @@
#include "util/string.h" #include "util/string.h"
#include "util/tracy_wrapper.h" #include "util/tracy_wrapper.h"
#include <vector> #include <vector>
#include <csignal>
#include <cstdarg> #include <cstdarg>
#include <cstdio> #include <cstdio>
#include <signal.h> #include <signal.h>
@ -81,31 +82,28 @@ namespace porting
Signal handler (grabs Ctrl-C on POSIX systems) Signal handler (grabs Ctrl-C on POSIX systems)
*/ */
static bool g_killed = false; volatile static std::sig_atomic_t g_killed = false;
bool *signal_handler_killstatus() volatile std::sig_atomic_t *signal_handler_killstatus()
{ {
return &g_killed; return &g_killed;
} }
#if !defined(_WIN32) // POSIX #if !defined(_WIN32) // POSIX
#define STDERR_FILENO 2
static void signal_handler(int sig) static void signal_handler(int sig)
{ {
if (!g_killed) { if (!g_killed) {
if (sig == SIGINT) { if (sig == SIGINT) {
dstream << "INFO: signal_handler(): " const char *dbg_text{"INFO: signal_handler(): "
<< "Ctrl-C pressed, shutting down." << std::endl; "Ctrl-C pressed, shutting down.\n"};
write(STDERR_FILENO, dbg_text, strlen(dbg_text));
} else if (sig == SIGTERM) { } else if (sig == SIGTERM) {
dstream << "INFO: signal_handler(): " const char *dbg_text{"INFO: signal_handler(): "
<< "got SIGTERM, shutting down." << std::endl; "got SIGTERM, shutting down.\n"};
write(STDERR_FILENO, dbg_text, strlen(dbg_text));
} }
// Comment out for less clutter when testing scripts
/*dstream << "INFO: sigint_handler(): "
<< "Printing debug stacks" << std::endl;
debug_stacks_print();*/
g_killed = true; g_killed = true;
} else { } else {
(void)signal(sig, SIG_DFL); (void)signal(sig, SIG_DFL);

View file

@ -13,6 +13,7 @@
#endif #endif
// Be mindful of what you include here! // Be mindful of what you include here!
#include <csignal>
#include <string> #include <string>
#include "config.h" #include "config.h"
#include "irrlichttypes.h" // u64 #include "irrlichttypes.h" // u64
@ -77,7 +78,7 @@ namespace porting
void signal_handler_init(); void signal_handler_init();
// Returns a pointer to a bool. // Returns a pointer to a bool.
// When the bool is true, program should quit. // When the bool is true, program should quit.
[[nodiscard]] bool *signal_handler_killstatus(); [[nodiscard]] volatile std::sig_atomic_t *signal_handler_killstatus();
/* /*
Path of static data directory. Path of static data directory.

View file

@ -65,6 +65,8 @@
#include "gettext.h" #include "gettext.h"
#include "util/tracy_wrapper.h" #include "util/tracy_wrapper.h"
#include <csignal>
class ClientNotFoundException : public BaseException class ClientNotFoundException : public BaseException
{ {
public: public:
@ -4114,7 +4116,7 @@ std::unique_ptr<PlayerSAO> Server::emergePlayer(const char *name, session_t peer
return playersao; return playersao;
} }
void dedicated_server_loop(Server &server, bool &kill) void dedicated_server_loop(Server &server, volatile std::sig_atomic_t &kill)
{ {
verbosestream<<"dedicated_server_loop()"<<std::endl; verbosestream<<"dedicated_server_loop()"<<std::endl;

View file

@ -25,6 +25,7 @@
#include "translation.h" #include "translation.h"
#include "script/common/c_types.h" // LuaError #include "script/common/c_types.h" // LuaError
#include <atomic> #include <atomic>
#include <csignal>
#include <string> #include <string>
#include <list> #include <list>
#include <map> #include <map>
@ -799,4 +800,4 @@ private:
Shuts down when kill is set to true. Shuts down when kill is set to true.
*/ */
void dedicated_server_loop(Server &server, bool &kill); void dedicated_server_loop(Server &server, volatile std::sig_atomic_t &kill);

View file

@ -9,6 +9,8 @@
#include "util/container.h" #include "util/container.h"
#include "log.h" #include "log.h"
#include "log_internal.h" #include "log_internal.h"
#include <csignal>
#include <set> #include <set>
#include <sstream> #include <sstream>
@ -45,7 +47,7 @@ public:
void setup( void setup(
ChatInterface *iface, ChatInterface *iface,
bool *kill_requested, volatile std::sig_atomic_t *kill_requested,
const std::string &nick) const std::string &nick)
{ {
m_nick = nick; m_nick = nick;
@ -96,9 +98,9 @@ private:
int m_rows; int m_rows;
bool m_can_draw_text; bool m_can_draw_text;
bool *m_kill_requested = nullptr; volatile std::sig_atomic_t *m_kill_requested = nullptr;
ChatBackend m_chat_backend; ChatBackend m_chat_backend;
ChatInterface *m_chat_interface; ChatInterface *m_chat_interface;
TermLogOutput m_log_output; TermLogOutput m_log_output;