Чтобы определить группу процесса для конкретного процесса, можно вызвать функцию getpgrp () языка Perl и передать функции kill () отрицательное значение идентификатора группы процесса для отправки одного и того же сигнала одновременно всем членам группы. Именно так действует командный интерпретатор, отправляя сигнал HUP всем своим подпроцессам непосредственно перед завершением работы. Дочерний процесс, вновь созданный путем ветвления, принадлежит к той же группе сеанса и группе процесса, что и его родительский процесс. Подобным ветвлением можно одновременно выполнять несколько задач.
Подпрограмма become_daemon ()
use POSIX 'setsid'; sub become_daemon { die "Can’t fork" unless defined (my $child = fork); exit 0 if $child; # Завершение родительского процесса setsid () ; # Преобразование в лидера сеанса open(STDIN,"open(STDOUT,">/dev/null"); open(STDERR,">&STDOUT"); chdir '/'; # Смена рабочего каталога umask (0); # Сброс маски режима создания файла $ENV{PATH} = '/bin:/sbin:/usг/bin:/usr/sbin'; return $$; }
Функция setsid() выполняет несколько действий. Она создает одновременно и новую группу сеанса, и новую группу процесса, а также преобразует текущий процесс в лидера сеанса. Одновременно она отделяет текущий процесс от управляющего терминала. В результате этот дочерний процесс становится полностью независимым для командного интерпретатора. Функция setsid() завершается аварийно, если данный процесс уже является лидером сеанса к моменту ее вызова (т.е. он находится па переднем плане), но выполненный перед этим вызов функции fork () гарантирует, что этого не произойдет.
После вызова функции setsid () дескрипторы файлов STDIN и STDOUT вновь открываются в специальное “ничего не выполняющее” устройство /dev/null, а дескриптор STDERR становится копией дескриптора STDOUT (строки 5-7). Это позволяет исключить возможность появления выходных данных демона на терминале. Затем вызывается функция chdir () для перехода из текущего каталога в корневой каталог файловой системы, переустанавливается маска создания файлов в значение 0 и переменная среды PATH определяется равной небольшому числу стандартных каталогов (строка 10). Возвращается новый идентификатор процесса из глобальной переменной $$. Поскольку было выполнено ветвление, теперь идентификатор процесса отличается от того, с которым была вызвана эта подпрограмма, и явный возврат нового значения PID таким образом — это для любого программиста хороший способ напомнить самому себе об этом факте.