Навигация

Демонами называют процессы, которые не имеют управляющего терминала и работают где-то в бэкграунде. Как этого добиться?

Во-первых, управляющий терминал привязан не к процессу, а к сессии. Значит, процесс должен завести себе новую сессию.

Во-вторых, лидер группы процессов не может делать setsid(2). Почему? Потому что в противном случае получилось бы, что лидер группы и остальные процессы группы находятся в разных сессиях, а это нарушило бы "strict two-level hierarchy of session and process groups" (setsid(2)). Поэтому процесс должен форкнуться, чтобы уж точно не быть лидером группы.

В-третьих, после fork(2) можно уже сделать setsid(2). Это перекинет процесс в новую сессию и сделает его лидером новой группы процессов (в которой пока никого больше нет). Более того, новая сессия не будет иметь управляющего терминала.

В-четвертых, мы все еще можем ненароком привязаться к управляющему терминалу. Если в процессе, не имеющем управляющего терминала, в системный вызов open(2) передать путь, ссылающийся на терминал, то этот терминал станет управляющим терминалом процесса (если только мы не укажем в аргументах флажок O_NOCTTY). К счастью, управляющий терминал можно привязать к сессии только в том процессе, который является ее лидером. Поэтому процесс должен форкнуться еще раз, чтобы не быть лидером сессии.

Процесс не имеет управляющего терминала и не может случайно к нему привязаться. Победа.

PS Если вы рискнёте читать что-нибудь на эту тему на русском, то доводим до сведения, что в этой статье обнаружено меньше всего ошибок. Если вы видите там расхождение с описанным нами, то правы мы (кто бы мог подумать).

PPS В линуксовых манах двойной форк упоминается, как минимум, в секции BUGS в man 3 daemon. А еще хороший "мануал" есть в комментариях к одному из примеров из Boost.Asio.