Операционная система UNIX - страница 82
>
> не имеющие управляющего терминала. Однако лидером группы и
> сеанса может стать процесс, если он еще не является лидером.
> Поскольку предыстория запуска данной программы неизвестна,
> необходима гарантия, что наш процесс не является лидером.
> Для этого порождаем дочерний процесс. Т.к. его PID уникален,
> то ни группы, ни сеанса с таким идентификатором не существует,
> а значит нет и лидера. При этом родительский процесс
> немедленно завершает выполнение, поскольку он уже не нужен.
> Существует еще одна причина необходимости порождения
> дочернего процесса. Если демон был запущен из командной строки
> командного интерпретатора shell не в фоновом режиме,
> последний будет ожидать завершения выполнения демона,
> и таким образом, терминал будет заблокирован.
> Порождая процесс и завершая выполнение родителя,
> имитируем для командного интерпретатора завершение
> работы демона, после чего shell выведет свое приглашение */
> if (fork () !=0)
> exit(0); /* Родитель заканчивает работу */
> /* Дочерний процесс с помощью системного вызова
> становится лидером новой группы, сеанса и не имеет
> ассоциированного терминала */
[28]
> }
> /* Теперь необходимо закрыть открытые файлы. Закроем
> все возможные файловые дескрипторы. Максимальное число
> открытых файлов получим с помощью функции 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) позволяет определить ряд опций ведения журнала. Она имеет следующее определение: