Строго говоря, двойная вилка не имеет ничего общего с повторным воспитанием демона как потомка init
. Все, что необходимо для повторного воспитания ребенка, это то, что родитель должен выйти. Это может быть сделано только с одной вилкой. Кроме того, двойное разветвление само по себе не переопределяет процесс демона init
; родитель демона должен выйти. Другими словами, родитель всегда выходит, когда разветвляет правильного демона, чтобы процесс демона был переназначен init
.
Так почему двойная вилка? POSIX.1-2008 Раздел 11.1.3, « Терминал управления », содержит ответ (выделение добавлено):
Управляющий терминал для сеанса назначается руководителем сеанса в зависимости от реализации. Если лидер сеанса не имеет управляющего терминала и открывает файл терминального устройства, который еще не связан с сеансом, без использования O_NOCTTY
опции (см. open()
), То определяется, будет ли реализация управляющим терминалом лидера сеанса. Если процесс, который не является лидером сеанса, открывает файл терминала или используется O_NOCTTY
опция open()
, то этот терминал не должен становиться управляющим терминалом вызывающего процесса .
Это говорит нам о том, что если процесс-демон делает что-то вроде этого ...
int fd = open("/dev/console", O_RDWR);
... тогда процесс-демон может быть выбран в /dev/console
качестве управляющего терминала в зависимости от того, является ли процесс-демон лидером сеанса, и в зависимости от реализации системы. Программа может гарантировать, что вышеуказанный вызов не получит управляющий терминал, если программа сначала гарантирует, что он не является лидером сеанса.
Обычно при запуске демона setsid
вызывается (от дочернего процесса после вызова fork
), чтобы отделить демон от его управляющего терминала. Однако вызов setsid
также означает, что вызывающий процесс будет лидером сеанса нового сеанса, что оставляет открытой возможность того, что демон может повторно захватить управляющий терминал. Метод двойного разветвления гарантирует, что процесс-демон не является лидером сеанса, что затем гарантирует, что вызов open
, как в примере выше, не приведет к тому, что процесс-демон повторно запросит управляющий терминал.
Техника двойной вилки немного параноидальна. В этом нет необходимости, если вы знаете, что демон никогда не откроет файл терминального устройства. Кроме того, в некоторых системах это может не потребоваться, даже если демон действительно открывает файл оконечного устройства, поскольку такое поведение определяется реализацией. Однако одна вещь, которая не определяется реализацией, состоит в том, что только лидер сеанса может выделить управляющий терминал. Если процесс не является лидером сеанса, он не может выделить управляющий терминал. Поэтому, если вы хотите быть параноиком и быть уверенным, что процесс-демон не может случайно получить управляющий терминал, независимо от специфики, определенной реализацией, тогда метод двойного разветвления является существенным.