SDL/С++ OpenGL Программа, как остановить SDL от ловли SIGINT
Я использую SDL для приложения OpenGL, работающего в Linux. Моя проблема в том, что SDL ловит SIGINT и игнорирует его. Это боль, потому что я развиваюсь через сеанс экрана, и я не могу убить запущенную программу с помощью CTRL-C (программа, на которой работает компьютер, подключена к проектору и не имеет устройств ввода).
Есть ли флаг или что-то, что я могу передать в SDL, чтобы он не захватил SIGINT? Я просто хочу, чтобы программа остановилась, когда она получила сигнал (т.е. Когда я нажимаю ctrl-c).
Ответы
Ответ 1
Ctrl-C на консоли генерирует событие SDL_QUIT. Вы можете следить за этим событием, используя SDL_PollEvent или SDL_WaitEvent, и выходить (чисто), когда он обнаружен.
Обратите внимание, что другие действия могут генерировать событие SDL_QUIT (например, попытка закрыть главное окно с помощью диспетчера окон).
Ответ 2
Я нашел ответ:
Флаг SDL_INIT_NOPARACHUTE будет фиксировать фатальные сигналы, чтобы SDL мог очистить после себя. Он работает для таких вещей, как SIGSEGV, но, судя по всему, SIGINT не достаточно смертелен.
Мое решение заключается в reset обработчике сигнала SIGINT после инициализации SDL:
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
signal(SIGINT, SIG_DFL);
Спасибо Cache за ввод, он поставил меня на правильный путь.
Майкл
Ответ 3
Передача флага инициализации SDL_INIT_NOPARACHUTE
в SDL_Init "Предотвращает обнаружение SDL фатальными сигналами".
См.: http://www.libsdl.org/cgi/docwiki.cgi/SDL_Init
Ответ 4
Если вы почему-то не используете цикл событий, вы можете использовать SDL_QuitRequested
в цикле "опрос".
Ответ 5
В SDL_quit.c есть проверка подсказок, чтобы определить, следует ли использовать обработчики сигналов в SDL_QuitInit()
. Не уверен, что это существовало в более старых версиях, когда задавался исходный вопрос, но может быть удобен для тех, кто приходит сюда свежими.
Просто протестированный в моем приложении Windows, теперь я могу снова получить все сигналы правильно, используя:
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
SDL_Init(...);