UNIX: разработка сетевых приложений
Например, демон может сделать следующий вызов, когда вызов функции
неожиданно оказывается неудачным:renamesyslog(LOG_INFO|LOG_LOCAL2, "rename(%s, %s): %m", file1, file2);Назначение аргументов
иfacilityв том, чтобы все сообщения, которые посылаются процессами определенного типа (то есть с одним значением аргументаlevel), могли обрабатываться одинаково в файлеfacilityили чтобы все сообщения одного уровня (с одинаковым значением аргумента/etc/syslog.conf) обрабатывались одинаково. Например, файл конфигурации может содержать строкиlevelkern.* /dev/consolelocal7.debug /var/log/cisco.logдля указания, что все сообщения ядра направляются на консоль, а сообщения относительно отладки со значением аргумента
, равнымfacility, добавляются в файлlocal7./var/log/cisco.logКогда приложение впервые вызывает функцию
, она создает дейтаграммный доменный сокет Unix и затем вызывает функциюsyslogдля сокета с заранее известным полным именем, которое создано демономconnect(например,syslogd). Этот сокет остается открытым, пока процесс не завершится. Другим вариантом является вызов процессом функций/var/run/logиopenlog.closelog#include <syslog.h>void openlog(const char *<i>ident</i>, int <i>options</i>, int <i>facility</i>);void closelog(void);Функция
может быть вызвана перед первым вызовом функцииopenlog, а функцияsyslog— когда приложение закончит отправлять сообщения в журнал.closelogАргумент
— это строка, которая будет добавлена в начало каждого журнального сообщения функциейident. Часто это имя программы.syslogОбычно аргумент
формируется путем применения операции логического ИЛИ к константам из табл. 13.3.optionsТаблица 13.3. Аргумент options (параметр) для функции openlog
Параметр Описание LOG_CONS Выводить журнал на консоль, если невозможно послать сообщение демону syslogd LOG_NDELAY Не откладывать создание сокета, открыть его сейчас LOG_PERROR Записывать сообщение в stderr, а также посылать его демону syslogd LOG_PID Включать идентификатор процесса (PID) в каждую запись журнала Обычно доменный сокет Unix не создается при вызове функции
. Вместо этого сокет открывается при первом вызове функцииopenlog. Параметрsyslogуказывает, что сокет должен создаваться при вызове функцииLOG_NDELAY.openlogАргумент
функцииfacilityзадает значениеopenlog, используемое по умолчанию для любого последующего вызова функцииfacility, при котором не задается аргументsyslog. Некоторые демоны вызывают функциюfacilityи задают значение аргументаopenlog(которое обычно не изменяется для данного демона) и затем в каждом вызове функцииfacilityзадают только аргументsyslog(посколькуlevelможет изменяться в зависимости от ошибки).levelСообщения для записи в журнал могут также генерироваться командой
. Это может использоваться в сценариях интерпретатора команд, например для отправки сообщений демонуlogger.syslogd13.4. Функция daemon_init
В листинге 13.1 [1] показана функция, называемая
, которую мы можем вызвать (обычно с сервера), чтобы придать процессу свойства демона.daemon_initЛистинг 13.1. Функция daemon_init: придание процессу свойств демона
//daemon _init.с1 #include "unp.h"2 #include <syslog.h>3 #define MAXFD 644 extern int daemon_proc; /* определен в error.с */5 int6 daemon_init(const char *pname, int facility)7 {8 int i;9 pid_t pid;10 if ((pid = Fork()) < 0)11 return (-1);12 else if (pid)13 _exit(0); /* родитель завершается */14 /* 1-й дочерний процесс продолжает работу... */15 if (setsid() < 0) /* становится главным процессом сеанса */16 return (-1);17 Signal(SIGHUP, SIG_IGN);18 if ((pid = Fork()) < 0)19 return (-1);20 else if (pid)21 _exit(0); /* 1-й дочерний процесс завершается */22 /* 2-й дочерний процесс продолжает работу */23 daemon_proc = 1; /* для функций err_XXX() */24 chdir("/"); /* смена текущего каталога */