Обратите внимание, что с Git 2.12 (1 квартал 2017 года, 6+ лет спустя) Ctrl + C в сеансе git-пейджера должен вести себя лучше.
См. коммит 46df690 , коммит 246f0ed , коммит 2b296c9 (07 января 2017) Джефф Кинг (peff
) .
(Объединено с Junio C Hamano - gitster
- в коммит 5918bdc , 18 января 2017 г.)
execv_dashed_external
: ждать ребенка в случае смерти
Набрав от ^C
до pager
, что обычно не убивает его, убил Git и снял пейджер как побочный урон в определенной структуре дерева процессов.
Это было исправлено.
Вы можете запустить любой внешний пунктир с помощью таких команд, как git -p stash list
, где команда завершает работу, но пейджер все еще идет.
Короткая версия - все должно нормально останавливаться (Git и пейджер)
Но подробно:
Когда git
запускает pager
, для процесса git важно
торчать и ждать, пока pager
закончится, даже если
больше нет данных для его подачи.
Это потому, что git
порождает pager
как дочерний элемент, и, таким образом, процесс git
является лидером сеанса на терминале. После того, как он умрет, pager
закончит текущее чтение с терминала
символ), а затем получите EIO
, пытаясь прочитать снова.
Примечание: EIO
(ошибка 5) для ошибки ввода / вывода и ( источник ):
ловушка для всевозможных неожиданных аппаратных ошибок. Это может быть из-за физической ошибки, но дополнительно, потерянный процесс (процесс, чей родитель умер), который пытается прочитать из стандартного ввода, получит это. Системы BSD возвращают это, если вы пытаетесь открыть устройство pty, которое уже используется.
Попытка чтения из закрытого потока вернет EIO, равно как и чтение или запись на диск, который находится за пределами физических границ устройства.
Открытие /dev/tty
, когда у процесса нет контроля tty, также будет выпадать EIO
.
Итак (назад к ^C
в pager
):
Когда вы нажимаете ^C
, это отправляет SIGINT
на git
и на pager
,
и это аналогичная ситуация.
pager
игнорирует его, но процесс git
должен зависать, пока не закончится пейджер. Мы говорили об этом давно в a3da882 (пейджер: до
wait_for_pager о смерти сигнала, 2009-01-22) .
Но когда у вас есть пунктирная внешняя строка (или псевдоним, указывающий на встроенную функцию, которая повторно выполнит git для встроенной функции), в миксе будет дополнительный процесс.
Например, запустив:
$ git -c alias.l=log l
будет иметь дерево процессов, подобное:
git (parent)
\
git-log (child)
\
less (pager)
Если вы нажмете ^C
, SIGINT
перейдет ко всем из них. Пейджер игнорирует его, и дочерний процесс git завершается в wait_for_pager ().
Но родительский процесс git умрет, и случится обычная проблема с EIO.