feat(servei): reinici real via execv
This commit is contained in:
1 parent
774874deb0
commit
a8ccb3fae1
5 files changed
+97
-11
No files matched your search
@@ -0,0 +1,51 @@
|
||||
// relaunch.cpp - Implementació del reinici en calent
|
||||
|
||||
#include "core/system/relaunch.hpp"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <process.h> // _execv
|
||||
#else
|
||||
#include <unistd.h> // execv
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// Estat global (process-scope). Aquesta TU és l'única que gestiona el
|
||||
// reinici, així que els statics interns no s'escapen.
|
||||
char** g_argv = nullptr;
|
||||
bool g_requested = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace System::Relaunch {
|
||||
|
||||
void setArgv(int /*argc*/, char** argv) {
|
||||
g_argv = argv;
|
||||
}
|
||||
|
||||
void request() {
|
||||
g_requested = true;
|
||||
}
|
||||
|
||||
void execIfRequested() {
|
||||
if (!g_requested || g_argv == nullptr || g_argv[0] == nullptr) {
|
||||
return;
|
||||
}
|
||||
std::cout << "[Relaunch] Reiniciant " << g_argv[0] << "...\n";
|
||||
#ifdef _WIN32
|
||||
_execv(g_argv[0], g_argv);
|
||||
#else
|
||||
execv(g_argv[0], g_argv);
|
||||
#endif
|
||||
// Si arribem aquí, execv ha fallat. Tots els subsistemes ja estan
|
||||
// destruïts; sortim amb error i el shell rebrà el codi.
|
||||
std::cerr << "[Relaunch] Ha fallat: " << std::strerror(errno) << '\n';
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
} // namespace System::Relaunch
|
||||
@@ -0,0 +1,28 @@
|
||||
// relaunch.hpp - Reinici en calent del procés (execv)
|
||||
//
|
||||
// Helper desacoblat perquè el menú de servei demani un reinici sense conèixer
|
||||
// ni Director ni main.cpp. Patró d'ús:
|
||||
//
|
||||
// main() → Relaunch::setArgv(argc, argv) (a l'arrencada)
|
||||
// ServiceMenu → Relaunch::request() (en activar "Reiniciar")
|
||||
// main() → Relaunch::execIfRequested() (al final de SDL_AppQuit)
|
||||
//
|
||||
// L'execv() reemplaça el procés actual: si torna, ha fallat. Es crida després
|
||||
// de destruir el Director per garantir que GPU/àudio/SDL ja són morts.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace System::Relaunch {
|
||||
|
||||
// Emmagatzema l'argv original. Cal cridar-ho una vegada des de main.
|
||||
void setArgv(int argc, char** argv);
|
||||
|
||||
// Demana un reinici (no actua immediatament; només marca el flag).
|
||||
void request();
|
||||
|
||||
// Si hi ha reinici demanat i tenim argv vàlid, fa execv. En cas d'èxit
|
||||
// no torna. Si execv falla, registra l'error per stderr i surt amb
|
||||
// EXIT_FAILURE (no podem reprendre — els subsistemes ja estan destruïts).
|
||||
void execIfRequested();
|
||||
|
||||
} // namespace System::Relaunch
|
||||
Reference in new issue
Block a user