diff --git a/source/director.cpp b/source/director.cpp index 5133086..f464aa6 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -3,12 +3,14 @@ #include // Para SDL_LogCategory, SDL_LogInfo, SDL_SetLogPriority, SDL_LogPriority, SDL_Quit #include // Para mkdir, stat, S_IRWXU -#include // Para getuid +#include +#include // Para getuid #include // Para errno, EEXIST, EACCES, ENAMETOOLONG #include // Para printf, perror #include // Para exit, EXIT_FAILURE, srand, rand, system #include // Para time +#include // Para std::cerr #include // Para make_unique, unique_ptr #include // Para span #include // Para runtime_error @@ -40,6 +42,11 @@ #include // Para getpwuid, passwd #endif +#ifdef _WIN32 +#include +#include +#endif + // Constructor Director::Director(int argc, std::span argv) { #ifdef RECORDING @@ -368,21 +375,77 @@ auto Director::run() -> int { return 0; } -// Apaga el sistema +// Apaga el sistema de forma segura void Director::shutdownSystem(bool should_shutdown) { - if (should_shutdown) { + if (!should_shutdown) { + return; + } + #ifdef _WIN32 - // Apaga el sistema en Windows - system("shutdown /s /t 5"); + // 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__ - // Apaga el sistema en macOS - system("sudo shutdown -h +0.1"); + // macOS: Usar execvp con fork + pid_t pid = fork(); + if (pid == 0) { + // Proceso hijo - ejecutar shutdown + char *args[] = { + const_cast("shutdown"), + const_cast("-h"), + const_cast("+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; + } + } else { + std::cerr << "Error: No se pudo crear proceso fork en macOS" << std::endl; + } + #elif __linux__ - // Apaga el sistema en Linux - system("sleep 5; shutdown -h now"); + // Linux: Usar execvp con fork + pid_t pid = fork(); + if (pid == 0) { + // Proceso hijo - primero sleep, luego shutdown + sleep(5); + char *args[] = { + const_cast("shutdown"), + const_cast("-h"), + const_cast("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 -// Sistema operativo no compatible #error "Sistema operativo no soportado" #endif - } } \ No newline at end of file