creat shutdown.h i system_utils.h

fix: arreglants uns includes per a windows
This commit is contained in:
2025-08-11 08:15:54 +02:00
parent 6011365330
commit 3df13fdfa6
9 changed files with 527 additions and 187 deletions

View File

@@ -1,22 +1,17 @@
// IWYU pragma: no_include <bits/chrono.h>
#include "director.h"
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogInfo, SDL_SetLogPriority, SDL_LogPriority, SDL_Quit
#include <sys/stat.h> // Para mkdir, stat, S_IRWXU
#include <sys/wait.h>
#include <unistd.h> // Para getuid
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_SetLogPriority, SDL_LogPriority, SDL_Quit
#include <cerrno> // Para errno, EEXIST, EACCES, ENAMETOOLONG
#include <cstdio> // Para printf, perror
#include <cstdlib> // Para exit, EXIT_FAILURE, srand, rand, system
#include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE
#include <ctime> // Para time
#include <iostream> // Para std::cerr
#include <iostream> // Para basic_ostream, operator<<, cerr, endl
#include <memory> // Para make_unique, unique_ptr
#include <span> // Para span
#include <stdexcept> // Para runtime_error
#include <string> // Para operator+, allocator, char_traits, operator==, string, basic_string
#include <string> // Para allocator, char_traits, operator==, string, basic_string, operator+
#include "asset.h" // Para Asset, AssetType
#include "asset.h" // Para Asset
#include "audio.h" // Para Audio
#include "input.h" // Para Input
#include "lang.h" // Para setLanguage
@@ -34,19 +29,12 @@
#include "sections/intro.h" // Para Intro
#include "sections/logo.h" // Para Logo
#include "sections/title.h" // Para Title
#include "shutdown.h" // Para resultToString, shutdownSystem, ShutdownResult
#include "system_utils.h" // Para createApplicationFolder, resultToString, Result
#include "ui/notifier.h" // Para Notifier
#include "ui/service_menu.h" // Para ServiceMenu
#include "utils.h" // Para Overrides, overrides, getPath
#ifndef _WIN32
#include <pwd.h> // Para getpwuid, passwd
#endif
#ifdef _WIN32
#include <winbase.h>
#include <windows.h>
#endif
// Constructor
Director::Director(int argc, std::span<char *> argv) {
#ifdef RECORDING
@@ -88,18 +76,14 @@ Director::~Director() {
// Inicializa todo
void Director::init() {
// Configuración inicial de parametros
Asset::init(executable_path_); // Inicializa el sistema de gestión de archivos
loadAssets(); // Crea el índice de archivos
Input::init(
Asset::get()->get("gamecontrollerdb.txt"),
Asset::get()->get("controllers.json")); // Carga configuración de controles
Options::setConfigFile(Asset::get()->get("config.txt")); // Establece el fichero de configuración
Options::setControllersFile(Asset::get()->get("controllers.json")); // Establece el fichero de configuración de mandos
Options::loadFromFile(); // Carga el archivo de configuración
loadParams(); // Carga los parámetros del programa
loadScoreFile(); // Carga el archivo de puntuaciones
Asset::init(executable_path_); // Inicializa el sistema de gestión de archivos
loadAssets(); // Crea el índice de archivos
Input::init(Asset::get()->get("gamecontrollerdb.txt"), Asset::get()->get("controllers.json")); // Carga configuración de controles
Options::setConfigFile(Asset::get()->get("config.txt")); // Establece el fichero de configuración
Options::setControllersFile(Asset::get()->get("controllers.json")); // Establece el fichero de configuración de mandos
Options::loadFromFile(); // Carga el archivo de configuración
loadParams(); // Carga los parámetros del programa
loadScoreFile(); // Carga el archivo de puntuaciones
// Inicialización de subsistemas principales
Lang::setLanguage(Options::settings.language); // Carga el archivo de idioma
@@ -200,56 +184,12 @@ void Director::checkProgramArguments(int argc, std::span<char *> argv) {
// Crea la carpeta del sistema donde guardar datos
void Director::createSystemFolder(const std::string &folder) {
#ifdef _WIN32
system_folder_ = std::string(getenv("APPDATA")) + "/" + folder;
#elif __APPLE__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
system_folder_ = std::string(homedir) + "/Library/Application Support" + "/" + folder;
#elif __linux__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
system_folder_ = std::string(homedir) + "/.config/" + folder;
auto result = SystemUtils::createApplicationFolder(folder, system_folder_);
{
// Intenta crear ".config", per si no existeix
std::string config_base_folder = std::string(homedir) + "/.config";
int ret = mkdir(config_base_folder.c_str(), S_IRWXU);
if (ret == -1 && errno != EEXIST) {
printf("ERROR CREATING CONFIG BASE FOLDER.");
exit(EXIT_FAILURE);
}
}
#endif
struct stat st = {0};
if (stat(system_folder_.c_str(), &st) == -1) {
errno = 0;
#ifdef _WIN32
int ret = mkdir(system_folder_.c_str());
#else
int ret = mkdir(system_folder_.c_str(), S_IRWXU);
#endif
if (ret == -1) {
switch (errno) {
case EACCES:
printf("the parent directory does not allow write");
exit(EXIT_FAILURE);
case EEXIST:
printf("pathname already exists");
exit(EXIT_FAILURE);
case ENAMETOOLONG:
printf("pathname is too long");
exit(EXIT_FAILURE);
default:
perror("mkdir");
exit(EXIT_FAILURE);
}
}
if (result != SystemUtils::Result::SUCCESS) {
std::cerr << "Error creando carpeta del sistema: "
<< SystemUtils::resultToString(result) << std::endl;
exit(EXIT_FAILURE);
}
}
@@ -377,75 +317,11 @@ auto Director::run() -> int {
// Apaga el sistema de forma segura
void Director::shutdownSystem(bool should_shutdown) {
if (!should_shutdown) {
return;
}
if (should_shutdown) {
auto result = SystemShutdown::shutdownSystem(5, true); // 5 segundos, forzar apps
#ifdef _WIN32
// Windows: Usar API nativa de Windows
if (!InitiateSystemShutdownA(
NULL, // lpMachineName (NULL = local machine)
"Sistema apagándose...", // lpMessage
5, // dwTimeout (5 segundos)
TRUE, // bForceAppsClosed
FALSE // bRebootAfterShutdown (FALSE = shutdown)
)) {
std::cerr << "Error: No se pudo iniciar el apagado en Windows. Código: "
<< GetLastError() << std::endl;
}
#elif __APPLE__
// macOS: Usar execvp con fork
pid_t pid = fork();
if (pid == 0) {
// Proceso hijo - ejecutar shutdown
char *args[] = {
const_cast<char *>("shutdown"),
const_cast<char *>("-h"),
const_cast<char *>("+0.1"),
NULL};
execvp("shutdown", args);
// Si execvp falla, salir del proceso hijo
std::cerr << "Error: execvp falló en macOS" << std::endl;
_exit(1);
} else if (pid > 0) {
// Proceso padre - esperar al hijo
int status;
waitpid(pid, &status, 0);
if (WEXITSTATUS(status) != 0) {
std::cerr << "Error: Comando shutdown falló en macOS" << std::endl;
if (result != SystemShutdown::ShutdownResult::SUCCESS) {
std::cerr << SystemShutdown::resultToString(result) << std::endl;
}
} else {
std::cerr << "Error: No se pudo crear proceso fork en macOS" << std::endl;
}
#elif __linux__
// Linux: Usar execvp con fork
pid_t pid = fork();
if (pid == 0) {
// Proceso hijo - primero sleep, luego shutdown
sleep(5);
char *args[] = {
const_cast<char *>("shutdown"),
const_cast<char *>("-h"),
const_cast<char *>("now"),
NULL};
execvp("shutdown", args);
// Si execvp falla, salir del proceso hijo
std::cerr << "Error: execvp falló en Linux" << std::endl;
_exit(1);
} else if (pid > 0) {
// Proceso padre - esperar al hijo
int status;
waitpid(pid, &status, 0);
if (WEXITSTATUS(status) != 0) {
std::cerr << "Error: Comando shutdown falló en Linux" << std::endl;
}
} else {
std::cerr << "Error: No se pudo crear proceso fork en Linux" << std::endl;
}
#else
#error "Sistema operativo no soportado"
#endif
}