Строго говоря, двойная вилка не имеет ничего общего с повторным воспитанием демона как потомка 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
, как в примере выше, не приведет к тому, что процесс-демон повторно запросит управляющий терминал.
Техника двойных вилок немного параноидальна. Это может не потребовать, если вы знаете , что демон никогда не откроет файл терминального устройства. Кроме того, в некоторых системах это может не потребоваться, даже если демон действительно открывает файл оконечного устройства, так как это поведение определяется реализацией. Однако одна вещь, которая не определяется реализацией, состоит в том, что только лидер сеанса может выделить управляющий терминал. Если процесс не является лидером сеанса, он не может выделить управляющий терминал. Поэтому, если вы хотите быть параноиком и быть уверенным, что процесс-демон не может случайно получить управляющий терминал, независимо от какого-либо определенные реализацией особенности, тогда метод двойного разветвления необходим.