nixp.ru v3.0

22 января 2017,
воскресенье,
06:41:58 MSK

DevOps с компанией «Флант»
Аватар пользователя DimkaS
DimkaS написал 13 февраля 2009 года в 16:20 (675 просмотров) Ведет себя как мужчина; открыл 84 темы в форуме, оставил 922 комментария на сайте.

Мне нужно написать простого демона, который бы в бесконечном цикле ковырял некоторый ресурс, а при получении SIGTERM закрывал бы ресурс и завершался. Я нашёл такую статью: Перевод Linux Daemon HOWTO. Из неё мне стало всё понятно, кроме собственно организации корректного завершения по SIGTERM. Помогите пож-та примером кода или ссылкой.

myst

man signal

Там всё просто, вешаешь свой handler на SIGTERM и в нём уже делаешь всё, что нужно, а потом exit().

DimkaS

В man signal только описание описание сигналов. А как обработчик вешать?

myst

man 3 signal блин.

DimkaS


$ man 3 signal
Нет справочного руководства для signal в разделе 3

Нашёл вот такой пример:

#include 
#include 
#include 
void handler(int v)
{
signal(SIGTERM, handler);
fprintf(stderr, "Signal handler called with %d\n", v);
}
int main(int argc, char **argv)
{
signal(SIGTERM, handler);
while (1)
sleep(3600);
return 0;
}
metal
DimkaS

$ man 3 signal
Нет справочного руководства для signal в разделе 3

Аналогично, но думаю его можно установить.

Нашёл вот такой пример:

Увидел, этот пример и сразу пошел за Стивенсоном. В нем прочитал:
* Сигнал надо переустанавливать каждый раз в неких древних системах;

* Функция signal появилась до posix и имеет разную семантику в разных системах, поэтому рекомендуется sigaction, но если столь древние системы не интересуют можно на это забить.

DimkaS

Вот конечный результат:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
void handler(int v) {
      signal(SIGTERM, handler);
      syslog(LOG_DAEMON || LOG_NOTICE, "Simple daemon received SIGTERM. Exiting...");
      closelog();
      exit(EXIT_SUCCESS);
}
int main(void) {
  /* Наши ID процесса и сессии */
  pid_t pid, sid;
  /* Ответвляемся от родительского процесса */
  pid = fork();
  if (pid < 0) {
    exit(EXIT_FAILURE);
  }
  /* Если с PID'ом все получилось, то родительский процесс можно завершить. */
  if (pid > 0) {
    exit(EXIT_SUCCESS);
  }
  /* Изменяем файловую маску */
  umask(0);
  /* Здесь можно открывать любые журналы */        
      syslog(LOG_DAEMON || LOG_NOTICE, "Simple daemon started.");
  /* Создание нового SID для дочернего процесса */
  sid = setsid();
  if (sid < 0) {
    /* Журналируем любой сбой */
    exit(EXIT_FAILURE);
  }
  /* Изменяем текущий рабочий каталог */
  if ((chdir("/")) < 0) {
    /* Журналируем любой сбой */
    exit(EXIT_FAILURE);
  }
  /* Закрываем стандартные файловые дескрипторы */
  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);
  /* Специфичная для демона инициализация проходит тут */
      signal(SIGTERM, handler);      
  /* Большой Цикл */
  while (1) {
      /* Делаем здесь чего-нибудь ... */
      sleep(30); /* ждем 30 секунд */
  }
  exit(EXIT_SUCCESS);
}

Выравнивания разные, т.к. код надёрган из разных мест.

myst

Я, блин, фалломорфирую просто. Нет manpage и всё, руки опустили. Ну, бля, сходи на сайт OpenBSD и почитай маны в online или сделай:

apt-get install glibc-doc manpages-dev
metal
DimkaS
Вот конечный результат:

...
void handler(int v) {
      signal(SIGTERM, handler);
...

Переустанавливаешь зачем, ведь все равно выходишь?

DimkaS
metal
Переустанавливаешь зачем, ведь все равно выходишь?

Ааа… Значит, каждый раз надо обработчик события заново устанавливать?

Я ж просто взял пример не особо вникая, вот и результат :)

Спасибо.

myst

По POSIX не надо каждый раз переустанавливать. POSIX утвердили BSD-семантику, когда handler не сбрасывается в default, каждый раз. Почитай уже man 3 signal наконец!

metal
myst
По POSIX не надо каждый раз переустанавливать. POSIX утвердили BSD-семантику, когда handler не сбрасывается в default, каждый раз. Почитай уже man 3 signal наконец!

По POSIX да, но он сумел отыскать пример более старого кода. Я уж подумал, что может не спроста :D

DimkaS

О, блин… Сколько нюансов.. Спасибо :)

ecobeingecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.