немедленно завершает выполнение, поскольку он уже не нужен.
Существует еще одна причина необходимости порождения
дочернего процесса. Если демон был запущен из командной строки
командного интерпретатора shell не в фоновом режиме,
последний будет ожидать завершения выполнения демона,
и таким образом, терминал будет заблокирован.
Порождая процесс и завершая выполнение родителя,
имитируем для командного интерпретатора завершение
работы демона, после чего shell выведет свое приглашение */
if (fork () !=0)
exit(0); /* Родитель заканчивает работу */
/* Дочерний процесс с помощью системного вызова
становится лидером новой группы, сеанса и не имеет
ассоциированного терминала */
[28] Использование вызова setsid(2) справедливо для UNIX System V. Для BSD UNIX процесс должен последовательно создать группу, лидером которой он становится, а затем открыть управляющий терминал и с помощью команды ioctl(2) TIOCNOTTY отключиться от него.
}
/* Теперь необходимо закрыть открытые файлы. Закроем
все возможные файловые дескрипторы. Максимальное число
открытых файлов получим с помощью функции getrlimit */
getrlimit(RLIMIT_NOFILE, &flim);
for (fd = 0; fd < flim.rlim_max; fd++)
close(fd);
/* Сменим текущий каталог на корневой */
chdir("/");
/* Заявим о себе в системном журнале. Для этого сначала
установим опции ведения журнала: каждая запись будет
предваряться идентификатором PID демона, при невозможности
записи в журнал сообщения будут выводиться на консоль,
источник сообщений определим как "системный демон"
(см. комментарии к функциям ведения журнала ниже). */
openlog("Скелет демона" , LOG_PID | LOG_CONS, LOG_DAEMON);
/* Отметимся */
syslog(LOG_INFO, "Демон начал плодотворную работу...");
closelog();
/* Далее следует текст программы, реализующий полезные функции
демона. Эта часть предоставляется читателю для собственной
разработки. */
...
}
В программе использовалось еще не обсуждавшаяся возможность системного журнала сообщений выполняющихся программ. Функцией генерации сообщений является syslog(3) , отправляющая сообщение демону системного журнала syslogd(1M) , который в свою очередь либо дописывает сообщения в системный журнал, либо выводит на их консоль, либо перенаправляет в соответствии со списком пользователей данной или удаленной системы. Конкретный пункт назначения определяется конфигурационным файлом ( /etc/syslog.conf). Функция имеет определение:
#include
void syslog(int priority, char *logstring, /* параметры*/...);
Каждому сообщению logstring
назначается приоритет, указанный параметром priority
. Возможные значения этого параметра включают:
LOG_EMERG |
Идентифицирует состояние "паники" в системе. Обычно рассылается всем пользователям. |
LOG_ALERT |
Идентифицирует ненормальное состояние, которое должно быть исправлено немедленно, например, нарушение целостности системной базы данных. |
LOG_CRIT |
Идентифицирует критическое событие, например, ошибку дискового устройства. |
LOG_ERR |
Идентифицирует различные ошибки. |
LOG_WARNING |
Идентифицирует предупреждения. |
LOG_NOTICE |
Идентифицирует события, которые не являются ошибками, но требуют внимания. |
LOG_INFO |
Идентифицирует информационные сообщения, как, например, использованное в приведенной программе. |
LOG_DEBUG |
Идентифицирует сообщение, обычно используемое только при отладке программы. |
Последний тип сообщений подсказывает еще одну возможность использования системного журнала — для отладки программ, особенно неинтерактивных.
Строка logstring
может включать элементы форматирования, такие же, как и в функции printf(3) , с одним дополнительным выражением %m
, которое заменяется сообщением, соответствующим ошибке errno
. При этом может осуществляться вывод значений дополнительных параметров.
Функция openlog(3) позволяет определить ряд опций ведения журнала. Она имеет следующее определение:
void openlog(char *ident, int logopt, int facility);
Строка ident
будет предшествовать каждому сообщению программы. Аргумент logopt
задает дополнительные опции, в том числе:
Читать дальше