Короткий вопрос: что должна делать оболочка, если она находится в сиротской группе процессов, которая не владеет tty? Но я рекомендую прочитать длинный вопрос, потому что это забавно.
Вот забавный и увлекательный способ превратить ваш ноутбук в переносной обогреватель, используя вашу любимую оболочку (если вы не один из тех странных tcsh):
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
Это приводит к тому, что bash привязывает процессор к 100%. zsh и рыбы делают то же самое, в то время как ksh и tcsh борются с чем-то о контроле над работой, а затем кили, что немного лучше, но не намного. О, и это агностик-атакующий платформа: OS X и Linux затронуты.
Мое (потенциально неправильное) объяснение выглядит следующим образом: дочерняя оболочка обнаруживает, что она не находится на переднем плане: tcgetpgrp(0) != getpgrp()
. Поэтому он пытается остановить себя: killpg(getpgrp(), SIGTTIN)
. Но его группа процессов осиротела, потому что ее родитель (программа C) был лидером и умер, а SIGTTIN, отправленный в сиротскую группу процессов, просто отброшен (иначе ничто не могло начать его снова). Поэтому дочерняя оболочка не останавливается, но она все еще находится в фоновом режиме, поэтому она делает все снова, сразу. Промыть и повторить.
Мой вопрос в том, как оболочка командной строки обнаруживает этот сценарий и что ему нужно делать? Моя мысль заключается в том, что оболочка пытается read
из stdin и просто выходит, если чтение дает EIO.
Спасибо за ваши мысли!
Изменить: я попытался выполнить чтение() на /dev/tty с нулевой длиной, и это удалось, что плохо. Чтобы получить EIO, я действительно должен быть готов прочитать некоторые данные из /dev/tty.
Изменить: Еще одна мысль, которая у меня была, была kill(getpgrp(), 0)
. Если группа процессов осиротела, я полагаю, что это всегда будет терпеть неудачу. Однако это может также потерпеть неудачу, потому что у меня нет разрешения на сигнализацию лидера сеанса.
Изменить: для тех, кто нашел это позже, то, что я закончил, описано в https://github.com/fish-shell/fish-shell/issues/422. Также, как будущее?