Очистка ncurses беспорядок в терминале после сбоя

Я рисую TUI, используя ncurses. Проблема в том, что всякий раз, когда моя программа получает seg-fault, мой терминал остается в беспорядке. Я не вижу, что я набираю. Это боль, потому что я работаю над ssh. Я смягчил некоторые эффекты, используя экран.

Я хотел бы знать, есть ли команда, которая обновит мой терминал после seg-fault в ncurses, чтобы мой терминал начал вести себя нормально.

Ответ 1

Команда

stty sane^J

выполнил задание.

ОБНОВЛЕНИЕ: На некоторых терминалах stty sane также работает.

Ответ 2

ncurses (любая реализация curses) устанавливает режимы терминала в raw и noecho во время работы и позволяет приложениям имитировать их с помощью raw и noraw, эхо и noecho. Он делает это для производительности, чтобы избежать ожидания при переключении между этими режимами.

Когда приложение вызывает endwin, ncurses восстанавливает режимы терминала. Он также может сделать это для reset_shell_mode, хотя endwin используется гораздо чаще.

Если ваше приложение выйдет из строя или выйдет без восстановления режимов терминала с помощью endwin, наиболее очевидной проблемой является то, что вы не можете видеть, что вы печатаете, и что нажатие enter не работает.

ncurses предоставляет обработчик сигнала, чтобы поймать инициированные пользователем сигналы SIGINT, SIGTERM и будет очищаться, когда они будут обнаружены. Он не пытается поймать SIGSEGV, потому что в этот момент ваше приложение мертво и попытка воскресить его, чтобы восстановить что-то, является непродуктивным.

Некоторые люди могут посоветовать использовать stty sane для восстановления режимов терминала. Это "работает", но на платформах Unix вероятность того, что ваш ключ стирания будет изменен до неожиданного значения. Это работает как ожидалось для Linux- и современных BSD-систем.

Однако, кроме того, ncurses обычно сбрасывает

  • цвета (цвета по умолчанию для терминала)
  • чертеж линии (отключен)
  • протокол мыши (чтобы отключить его)

Если ваше приложение использует любую из этих функций, то команда reset является подходящим выбором. Обычно он очищает экран (возможно, не то, что нужно). И он использует меньше символов:

reset control J
 stty sane control J

Дальнейшее чтение:

Ответ 3

Команда

reset

также работал на меня на Ubuntu, возможно, переполненный. Лучше всего было установить псевдоним вроде:

alias 'clean'='stty sane;clear;'

в моем .bash_aliases, поскольку я обнаружил, что мне нужно сделать это много в отладке.

Ответ 4

Напишите обработчик сигнала для SIGSEGV и т.д., который вызывает endwin().

Ответ 5

У меня недавно была эта проблема на терминале Mac OSX. Следующий набор команд работал, тогда как stty sane - нет.

stty discard '^O'
stty dsusp '^Y'
stty eof '^D'
stty eol '^@'
stty eol2 '^@'
stty erase '^?'
stty intr '^C'
stty kill '^U'
stty lnext '^V'
stty min 1
stty quit '^\'
stty reprint '^R'
stty start '^Q'
stty status '^T'
stty stop '^S'
stty susp '^Z'
stty time 0
stty werase '^W'