В подразделе 34.7.1 мы видели, что сигналы SIGTTIN и SIGTTOU передаются фоновому процессу, если тот пытается соответственно прочитать или записать данные в контролирующем терминале (в последнем случае должен быть установлен флаг TOSTOP). Однако в передаче их «осиротевшей» группе процессов нет никакого смысла, поскольку, остановившись, она уже никогда не возобновит работу. По этой причине вместо отправки сигналов SIGTTIN и SIGTTOU ядро завершает операции чтения и записи ошибкой EIO.
Аналогично, если сигналы SIGTSTP, SIGTTIN и SIGTTOU должны привести к остановке «осиротевшей» группы процессов, их доставка просто отменяется (если же сигнал имеет соответствующий обработчик, он доставляется процессу). Это происходит вне зависимости от способа отправки — то есть сигнал может быть сгенерирован драйвером терминала или передан посредством явного вызова kill().
Сессии и группы процессов (известные также как задания) составляют двухуровневую иерархию: сессия представляет собой набор групп, а группы — набор процессов. Лидером сессии является процесс, который создал ее с помощью вызова setsid(). Аналогично лидером группы является процесс, который создал ее с помощью вызова setpgid(). Все участники группы процессов имеют один и тот же идентификатор PGID (который совпадает с PGID ее лидера), а все процессы из всех групп, составляющих сессию, имеют один и тот же идентификатор SID (который совпадает с SID ее лидера). Любая сессия может иметь контролирующий терминал, который устанавливается при открытии лидером сессии устройства /dev/tty. Открытие контролирующего терминала также приводит к тому, что лидер сессии становится контролирующим процессом этого терминала.
Сессии и группы процессов были созданы для поддержки управления заданиями (хотя иногда их можно применять и для других целей). В этом контексте командная оболочка является лидером сессии и контролирующим процессом для терминала, в котором она выполняется. Каждое задание (обычная команда или конвейер), запускаемое командной оболочкой, выполняется в отдельной группе процессов и может иметь три состояния (переключаться между которыми можно с помощью встроенных в оболочку команд): активная работа, работа в фоне и остановка в фоновом режиме.
Для поддержки управления заданиями драйвер терминала хранит запись для активной группы процессов (задания) контролирующего терминала. Он также доставляет сигналы активному заданию при нажатии определенного сочетания клавиш. Эти сигналы либо завершают, либо приостанавливают активную группу процессов.
Понятие активного задания терминала также используется для распределения запросов ввода/вывода. Только процессы из активной группы могут считывать данные из контролирующего терминала. Фоновым заданиям при попытке чтения передается сигнал SIGTTIN, стандартным действием которого является остановка всей группы процессов. Если в контролирующем терминале установлен флаг TOSTOP, при попытке записи в него фоновые задания получают сигнал SIGTTOU, действие по умолчанию которого тоже приводит к остановке группы процессов.
Когда сессия отключается от терминала, ядро передает контролирующему процессу сигнал SIGHUP, уведомляя его об этом факте. Это событие может запустить цепную реакцию, доставляя сигнал SIGHUP множеству других процессов. Во-первых, если командная оболочка является контролирующим процессом (что является обычной ситуацией), то при завершении она отправляет SIGHUP каждому процессу в группе, которую она создала. Во-вторых, если SIGHUP приводит к завершению контролирующего процесса, ядро передает его всем участникам активной группы контролирующего терминала.
В целом, приложениям не обязательно знать о сигналах управления заданиями. Исключением являются программы, работающие с экраном. Такие программы должны корректно обрабатывать сигнал SIGTSTP, сбрасывая атрибуты терминала к подходящим значениям перед остановкой и восстанавливая их при возобновлении работы после получения сигнала SIGCONT.
Группа процессов считается «сиротой», если ни один из ее участников не имеет родителя в другой группе в рамках той же сессии. Это важно понимать, поскольку за пределами группы нет такого процесса, который мог бы как отслеживать состояние остановленных процессов внутри группы, так и перезапускать их с помощью сигнала SIGCONT. Это могло бы привести к тому, что остановленные процессы оставались бы в системе навсегда. Чтобы этого избежать, все участники группы процессов, которая становится осиротевшей, получают два последовательных сигнала — SIGHUP и SIGCONT, которые уведомляют их о том, что они стали «сиротами», и обеспечивают их перезапуск.