Estritamente falando, a bifurcação dupla não tem nada a ver com re-criação do daemon como filho de init
. Tudo o que é necessário para re-pai do filho é que ele deve sair. Isso pode ser feito com apenas um único garfo. Além disso, fazer uma bifurcação por si só não reinicia o processo daemon init
; o pai do daemon deve sair. Em outras palavras, o pai sempre sai quando bifurca um daemon adequado, para que o processo do daemon seja re-pai init
.
Então, por que o garfo duplo? A Seção 11.1.3 do POSIX.1-2008 , " O terminal de controle ", tem a resposta (ênfase adicionada):
O terminal de controle de uma sessão é alocado pelo líder da sessão de uma maneira definida pela implementação. Se um líder de sessão não tiver um terminal de controle e abrir um arquivo de dispositivo de terminal que ainda não esteja associado a uma sessão sem usar a O_NOCTTY
opção (consulte open()
), será definido como implementação se o terminal se tornará o terminal de controle do líder de sessão. Se um processo que não seja um líder de sessão abrir um arquivo de terminal ou a O_NOCTTY
opção for usada open()
, esse terminal não se tornará o terminal de controle do processo de chamada .
Isso nos diz que, se um processo daemon fizer algo assim ...
int fd = open("/dev/console", O_RDWR);
... o processo daemon pode adquirir /dev/console
como seu terminal de controle, dependendo se o processo daemon é um líder de sessão e dependendo da implementação do sistema. O programa pode garantir que a chamada acima não adquira um terminal de controle se o programa primeiro garantir que não é um líder de sessão.
Normalmente, ao iniciar um daemon, setsid
é chamado (do processo filho após a chamada fork
) para dissociar o daemon do seu terminal de controle. No entanto, chamar setsid
também significa que o processo de chamada será o líder da nova sessão, o que deixa em aberto a possibilidade de o daemon recuperar novamente um terminal de controle. A técnica de bifurcação dupla garante que o processo daemon não seja o líder da sessão, o que garante que uma chamada para open
, como no exemplo acima, não resultará no processo daemon recuperando um terminal de controle.
A técnica de garfo duplo é um pouco paranóica. Pode não ser necessário se você souber que o daemon nunca abrirá um arquivo de dispositivo do terminal. Além disso, em alguns sistemas, pode não ser necessário, mesmo que o daemon abra um arquivo de dispositivo do terminal, pois esse comportamento é definido pela implementação. No entanto, uma coisa que não é definida pela implementação é que apenas um líder de sessão pode alocar o terminal de controle. Se um processo não for um líder de sessão, ele não poderá alocar um terminal de controle. Portanto, se você deseja ser paranóico e ter certeza de que o processo daemon não pode adquirir inadvertidamente um terminal de controle, independentemente de quaisquer especificações definidas pela implementação, a técnica de bifurcação dupla é essencial.