(Повторна публікація в unix за пропозицією на /programming/13718394/what-should-interactive-shells-do-in-orphaned-process-groups )
Коротке запитання полягає в тому, що повинна робити оболонка, якщо вона в групі осиротілих процесів, яка не володіє tty? Але рекомендую прочитати довге запитання, бо це забавно.
Ось цікавий та захоплюючий спосіб перетворити ваш ноутбук у портативний обігрівач простору, використовуючи улюблену оболонку (якщо ви не є одним із цих диваків tcsh):
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
Це змушує баш прив’язувати процесор на 100%. zsh і fish роблять те ж саме, тоді як ksh і tcsh нарікають щось на тему контролю над роботою, а потім перебирають кіль, що трохи краще, але не набагато. О, і це злочинець злочинця на платформі: OS X і Linux постраждали.
Мій (потенційно неправильно) пояснення полягає в наступному: дитина оболонка визначає , що вона не на передньому плані: tcgetpgrp(0) != getpgrp()
. Тому він намагається зупинити себе: killpg(getpgrp(), SIGTTIN)
. Але його процесна група осиротіла, тому що її батько (програма С) був лідером і помер, а SIGTTIN
відправлений до осиротілої групи процесів просто відкидається (інакше нічого не може запустити його заново). Тому дочірню оболонку не зупиняють, але вона все ще знаходиться на задньому плані, тому це робить все знову, відразу. Промийте і повторіть.
Моє запитання: як оболонка командного рядка може виявити цей сценарій, і що це правильно? У мене є два рішення, жодне з яких не є ідеальним:
- Спробуйте подати сигнал, чий pid відповідає нашому ідентифікатору групи. Якщо це не вдається
ESRCH
, це означає, що ми, ймовірно, сироти. - Спробуйте не блокувати зчитування одного байта від
/dev/tty
. Якщо це не вдаєтьсяEIO
, це означає, що ми, ймовірно, сироти.
(Наше відстеження цього питання - https://github.com/fish-shell/fish-shell/isissue/422 )
Дякуємо за ваші думки!