Я хотел бы вызвать функцию очистки после нажатия пользователем
маленькая буква «х» в правом верхнем углу окна консоли.
Я зарегистрировал atexit
метод, но это не вызывается в этом случае.
Решение должно работать на Windows и Linux.
Вы не можете использовать atexit здесь, потому что он вызывается, когда процесс завершается нормально, тогда как в вашем случае процесс завершается сигналом.
На linux
, SIGHUP (сигнал зависает) отправляется процессу, когда его управляющий терминал закрыт, и вы можете использовать обработку сигналов POSIX.
На windows
, Событие CTRL_CLOSE_EVENT доставлено, и вы можете использовать SetConsoleCtrlHandler Винапи справится с этим.
Итак, насколько мне известно, нет независимого от платформы способа справиться с этим в c++
, Вы должны использовать зависимый от платформы код, чтобы сделать это, как показано в следующей простой программе. Я проверял это на Windows с VS и на Ubuntu с G ++. Обратите внимание, что обработка ошибок была опущена, и ввод / вывод выполняется в обработчиках сигналов для простоты.
Программа регистрирует обработчик сигнала и atexit
функция. Затем он спит в течение 10 секунд. Если вы не закроете консоль в течение 10 секунд, процесс завершится нормально, и atexit
обработчик будет вызван. Если вы закроете окно до 10 секунд, он поймает сигнал. В Linux вы не увидите, как вызывается обработчик сигнала, но он вызывается, вы можете проверить это, написав файл (или издав звуковой сигнал?), Хотя я не рекомендую это делать.
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#include <stdio.h>
#include <stdlib.h>#ifdef WIN32
BOOL sig_handler(DWORD signum)
{
switch( signum )
{
case CTRL_CLOSE_EVENT:
printf( "Ctrl-Close event\n" );
return( TRUE );
default:
return FALSE;
}
}
#else
void sig_handler(int signum)
{
/* you won't see this printed, but it runs */
printf("Received signal %d\n", signum);
}
#endifvoid exit_fn(void)
{
printf("%s\n", __FUNCTION__);
}void setup_signal_handler()
{
#ifdef WIN32
SetConsoleCtrlHandler((PHANDLER_ROUTINE)sig_handler, TRUE);
#else
struct sigaction sa;
sa.sa_handler = &sig_handler;
sigfillset(&sa.sa_mask);
sigaction(SIGHUP, &sa, NULL);
#endif
}int main(void)
{
printf("%s\n", __FUNCTION__);
/* setup signal handler */
setup_signal_handler();
/* setup function to be called at normal process termination */
atexit(exit_fn);
/* sleep for 10s */
#ifdef WIN32
Sleep(10000);
#else
sleep(10);
#endif
/* print message if process terminates normally */
printf("Normal process termination\n");
exit(EXIT_SUCCESS);
}
Других решений пока нет …