Створення демона (служби) в linux, it tip - tricks

Чого я ніяк не міг припустити, так це того, що на моїй роботі мені випаде можливість або скоріше з'явиться необхідність писати що-небудь під linux. Однак така подія відбулася. Незважаючи на те, що за службовим обов'язком я є PHP-розробником (веб-розробником) мені «запропонували» написати утиліту під Ubuntu для починається проекту. І не просто утиліту а демона - службу під linux. Ще пару років тому подібного роду завдання могла б налякати мене. Але тільки не тепер. Тим більше що для розробки під Linux зовсім необов'язково мати специфічне програмне забезпечення. Компілятор C ++ вже є. Однак я давно збирався спробувати крос платформену середу для розробки ПО Lazarus. І я вирішив створювати демона на FreePascal.

Отже, тут я спробую показати приклад створення найпростішого демона в Lazarus.

Структура основної програми виглядає так само, як і звичайного консольного застосування:

Основна ідея при створенні демона полягає в наступному: створюється ще один екземпляр додатку в пам'яті а поточна програма завершується. Таким чином і стартує демон. Для реалізації цього підходу використовується функція fpFork. Вона створює копію поточного процесу і повертає:

  • PID, якщо процес успішно створений;
  • -1, якщо виникла помилка при створенні процесу;
  • 0, якщо це вже копія процесу (нащадок).

Таким чином старт демона здійснюється за допомогою нескладних операцій:

При запуску програми ми робимо копію нашого процесу, і якщо це пройшло успішно, завершуємо роботи (потрапляємо в гілку case else). Дочірній же процес починає свою роботу, потрапляючи в гілку case 0 і слід далі за кодом програми. Тепер демон переходить в режим очікування і чекає сигналу, після якого він активізується і виконає певні дії. У найпростішому випадку це можна організувати у вигляді циклу:

Цей цикл буде виконуватися до тих пір поки не прийде сигнал про знищення. Тепер необхідно навчити демон приймати зовнішні сигнали від ОС. Для цього створимо функцію, яка буде обробляти сигнали:

І тепер переспрямуємо обробку сигналів на цю функцію:

Тепер, якщо наш демон отримає сигнал про знищення sigTerm, він буде завершений. Залишається придумати механізм запуску і зупинки демона. Зараз я реалізував це досить простим способом. При запуску демона перевіряється який параметр йому переданий. Якщо start, то ФОРКОМ, створюємо в тимчасовій директорії файл daemonname.lock і пишемо туди pid демона. Якщо ж в якості параметра переданий stop відкриваємо файл daemonname.lock, Новомосковський pid, вбиваємо процес з таким pid, видалити lock файл. Однак, ймовірно, це не найкраще рішення. Тому має бути ще провести дослідження в цьому напрямку.

Повний код демона: