Ответ 1
В соответствии с расширенным программированием Stevens в главе 13 UNIX Environment, это процедура создания хорошего демона Unix:
- Вилка и родительский выход. Это означает, что оболочка или boot script считают, что команда выполнена. Кроме того, дочерний процесс гарантированно не является лидером группы процессов (предварительное условие для setid next)
- Вызовите
setsid
, чтобы создать новый сеанс. Это делает три вещи:- Процесс становится лидером сеанса нового сеанса.
- Процесс становится лидером группы процессов новой группы процессов.
- Процесс не имеет управляющего терминала
- Опционально снова вилка и выход из родителя. Это гарантирует, что демон не является лидером сеанса и не может получить управляющий терминал (под SVR4).
- Измените текущий рабочий каталог на
/
, чтобы избежать вмешательства в установку и размонтирование - Установите маску создания режима файла на 000, чтобы позднее разрешить создание файлов с любым необходимым разрешением.
- Закройте ненужные дескрипторы файлов, унаследованные от родителя (в любом случае нет управляющего терминала):
stdout
,stderr
иstdin
.
В настоящее время существует файл для отслеживания PID, который в значительной степени используется сценариями загрузки дистрибутива Linux. Обязательно запишите PID внука, либо возвращаемое значение второй вилки (шаг 3), либо значение getpid()
после шага 3.
Вот реализация Ruby, в основном переведенная из книги, но с двойной вилкой и выписывающей PID демона.
# Example double-forking Unix daemon initializer.
raise 'Must run as root' if Process.euid != 0
raise 'First fork failed' if (pid = fork) == -1
exit unless pid.nil?
Process.setsid
raise 'Second fork failed' if (pid = fork) == -1
exit unless pid.nil?
puts "Daemon pid: #{Process.pid}" # Or save it somewhere, etc.
Dir.chdir '/'
File.umask 0000
STDIN.reopen '/dev/null'
STDOUT.reopen '/dev/null', 'a'
STDERR.reopen STDOUT