10.9. Сигналы, передающиеся через fork() и exec()
10.9. Сигналы, передающиеся через fork() и exec()
Когда программа вызывает fork(), ситуация с сигналами в порожденном процессе почти идентична ситуации в родительском процессе. Установленные обработчики остаются на месте, заблокированные сигналы остаются заблокированными и т.д. Однако, любые ожидающие в родителе сигналы в потомке сбрасываются, включая установленный с помощью alarm() временной интервал. Это просто, и это имеет смысл.
Когда процесс вызывает одну из функций exec(), положение в новой программе следующее:
• Сигналы с установленным действием по умолчанию остаются с этим действием по умолчанию.
• Все перехваченные сигналы сбрасываются в состояние с действием по умолчанию.
• Сигналы, которые игнорируются, продолжают игнорироваться. Особым случаем является SIGCHLD. Если SIGCHLD до вызова exec() игнорировался, он может игнорироваться также и после вызова. В качестве альтернативы для него может быть восстановлено действие по умолчанию. То, что происходит на самом деле, стандартом POSIX намеренно не определяется. (Справочные страницы GNU/Linux не определяют, что делает Linux, и поскольку POSIX оставляет это не определенным, любой код, который вы пишете для использования SIGCHLD, должен быть подготовлен для обработки любого случая.)
• Сигналы, заблокированные до вызова exec(), остаются заблокированными и после вызова. Другими словами, новая программа наследует маску сигналов существующего процесса.
• Любые ожидающие сигналы (те, которые появились, но были заблокированы) сбрасываются. Новая программа не может их получить.
• Временной интервал, остающийся для alarm(), сохраняется на своем месте. (Другими словами, если процесс устанавливает alarm, а затем непосредственно вызывает exec(), новый образ в конечном счете получит SIGALARM. Если он сначала вызывает fork(), родитель сохраняет установки alarm, тогда как потомок, вызывающий exec(), не сохраняет.
ЗАМЕЧАНИЕ. Многие, если не все. программы предполагают, что сигналы инициализированы действиями по умолчанию и что заблокированных сигналов нет. Таким образом, особенно если не вы писали программу, запускаемую с помощью exec(), можно разблокировать перед вызовам exec() все сигналы