Пример приложения демона на С++

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Dima2387
Интересующийся
Сообщения: 9
Зарегистрирован: 21 ноя 2014, 17:35
Контактная информация:

Пример приложения демона на С++

Непрочитанное сообщение Dima2387 » 22 ноя 2014, 22:40

Народ искал в инете исходный код демона на С++ но не могу найти, есть примеры только на С++. Мог бы кто-то показать исходный код максимально простого демона на С++?
Программирование в Linux с нуля http://linuxdevelop.net/

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Пример приложения демона на С++

Непрочитанное сообщение Olej » 23 ноя 2014, 00:37

Dima2387 писал(а):исходный код демона на С++ но не могу найти, есть примеры только на С++.
Это, наверное, описка?
Имелось в виду "есть примеры только на С"?
Dima2387 писал(а):Мог бы кто-то показать исходный код максимально простого демона на С++?
1. Такие системнозависимые вещи как демоны и др. в UNIX (и в Linux как в одном из UNIX) пишутся на C. Вся система сама по себе написана на C.

2. Но практически любой код на C (за очень-очень редкими исключенирями), вы можете в неизменном виде скомпилировать компилятором C++, а, поскольку и тот и другой у вас - это компилятор GCC (с наибольшей вероятностью), то вы можете всё того же демона C вместо

Код: Выделить всё

$ gcc demon.c -o demon
...

просто скомпилировать в режиме C++:

Код: Выделить всё

$ g++ demon.c -o demon
...

Вот вам и демон на C++.
Это, конечно, относится только к коду юзерспес (не ядра, не модулей ядра), но у вас как-раз такой случай.

3. Вывод: вы можете взять любой пример демона на C, в котором выполняются все требования для демона, выбросить оттуда "начинку", и вставить свой код C++, и откомпилировать как C++.
Это связано с тем, что из C++ вы можете не задумываясь вызывать все POSIX API вызовы C, и у вас всё получится.
Всё равно, любой откомпилированный код C++ не может выполняться без стандартной библиотеки C libc.so, которая для C++, и практически всех других языков в Linux, является интерфейсом, шлюзом к системным вызовам.

4. Предостережение: в связи с переходом всех дистрибутивов на систему инициализации и управления сервисами systemd (Fedora в 2013г., все остальные в 2014г.), для написания демонов под systemd требования изменены ... не сильно, но изменены.
Как следствие, все примеры, написанные за 45 лет в UNIX будут некорректными. ;-)
Потребуют корректировки.
Какой корректировки? - см. в оригинальном описании systemd от его автора Ленарта Поттеринга (это единственный источник!). Есть отличный перевод, синхронно обновляемый. Я где-то давал ссылки в теме о systemd ... если попадётся - впишу сюда.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Пример приложения демона на С++

Непрочитанное сообщение Olej » 25 ноя 2014, 15:30

Dima2387 писал(а):Мог бы кто-то показать исходный код максимально простого демона на С++?
Вопрос хороший, уместный.
И даже не потому, чтоб на C++, а просто пора сесть подвести итоги по написанию демонов на сегодня, потому как основные описания на этот предмет написаны лет 20 назад, и для каких-то таких систем UNIX, которые на сегодня и не сыскать.

Самое обстоятельное описание предмета см. в книге:
У. Ричард Стивенс, Стивен Раго
UNIX. Профессиональное программирование

Изображение
Потому как, по моему мнению, если что-то есть описано в книгах у Стивенса, то это лучшее из описаний, существующих в природе.
13. Процессы-демоны.................................................................................504
13.1. Введение........................................................................................504
13.2. Характеристики демонов..............................................................504
13.3. Правила программирования демонов..........................................506
13.4. Журналирование ошибок.............................................................510
13.5. Демоны в единственном экземпляре...........................................515
13.6. Соглашения для демонов..............................................................517
13.7. Модель клиент-сервер..................................................................522
13.8. Подведение итогов........................................................................522
Книгу и архив примеров я прикреплю (хоть это и холивар :-? ... но не я же её готовил и выкладывал сотнями копиями в сеть?).

Ещё одна книжка, которая полезна в этом деле (по крайней мере для начального ознакомления) - это
Робачевский Андрей Михайлович
Операционная система UNIX. 2-е изд.

Изображение
ПРОЦЕССЫ .......................................... 146
Идентификаторы процесса .................. 147
Выделение памяти ............................... 150
Создание и управление процессами .. 154
Сигналы ................................................. 160
Надежные сигналы ............................ 166
Группы и сеансы ..................................... 173
Текущие и фоновые группы процессов .. 175
Ограничения ............................................ 177
ПРИМЕРЫ ПРОГРАММ ............................ 180
Демон ....................................................... 180
Командный интерпретатор ..................... 184
Вложения
unix_prof_prog_rus.pdf
(7.65 МБ) 279 скачиваний
unix_prof_prog.tgz
(113.1 КБ) 265 скачиваний
. Робачевский - Операционная система UNIX.pdf
(8.11 МБ) 263 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Пример приложения демона на С++

Непрочитанное сообщение Olej » 25 ноя 2014, 16:06

Olej писал(а): 4. Предостережение: в связи с переходом всех дистрибутивов на систему инициализации и управления сервисами systemd (Fedora в 2013г., все остальные в 2014г.), для написания демонов под systemd требования изменены ... не сильно, но изменены.
Как следствие, все примеры, написанные за 45 лет в UNIX будут некорректными. ;-)
Потребуют корректировки.
Какой корректировки? - см. в оригинальном описании systemd от его автора Ленарта Поттеринга (это единственный источник!). Есть отличный перевод, синхронно обновляемый. Я где-то давал ссылки в теме о systemd ... если попадётся - впишу сюда.
Ещё один вопрос в написании демонов: разобраться что там наворотил Ленарт Поттеринг в systemd. :-o
Он где-то явно пишет, что требования к грамотно написанным демонам при этом незначительно, но изменяются...
Я детально не разбирался в этом вопросе ... но теперь придётся разобраться ;-) .

Вот тот регулярно обновляемый перевод описания от Поттеринга.
Я прикреплю текущую его копию, поскольку ссылка эта когда доступна, а когда и нет (я уже на это попадался).
systemd для администраторов
Lennart Poettering (автор)*
Сергей Пташник (русский перевод)†
Данный документ доступен на условиях лицензии CC-BY-SA 3.0 Unported
18 ноября 2014 г.
s4a_latest.pdf
(1.12 МБ) 278 скачиваний
P.S. Но я отчётливо помню, что видел где-то оригинальный текст от Поттеринга с конкретным перечислением требований к написанию демона! :-?
Где-то вот в этой огромной подборке разрознённых статей по systemd, наверное.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Пример приложения демона на С++

Непрочитанное сообщение Olej » 25 ноя 2014, 16:58

Olej писал(а): Робачевский Андрей Михайлович
Операционная система UNIX. 2-е изд.
Вот "демон по Робачевскому" ;-), (стр.181) :
При описании взаимодействия процессов с терминалом и пользователем в
разделе "Группы и сеансы", отмечалось особое место демонов, которые не
имеют управляющего терминала. Теперь в отношении демонов можно
сформулировать ряд правил, определяющих их нормальное функциониро
вание, которые необходимо учитывать при разработке таких программ:
1. Демон не должен реагировать на сигналы управления заданиями,
посылаемые ему при попытке операций ввода/вывода с управляющим
терминалом. Начиная с некоторого времени, демон снимает ассоциацию
с управляющим терминалом, но на начальном этапе запуска ему
может потребоваться вывести то или иное сообщение на экран.
2. Необходимо закрыть все открытые файлы (файловые дескрипторы),
особенно стандартные потоки ввода/вывода. Многие из этих файлов
представляют собой терминальные устройства, которые должны быть
закрыты, например, при выходе пользователя из системы. Предполагается,
что демон остается работать и после того, как пользователь "покинул"
UNIX.
3. Необходимо снять его ассоциацию с группой процессов и управляющим
терминалом. Это позволит демону избавиться от сигналов, генерируемых
терминалом (SIGINT или SIGHUP) например, при нажатии
определенных клавиш или выходе пользователя из системы.
4. Сообщения о работе демона следует направлять в специальный журнал
с помощью функции syslog(3), — это наиболее корректный способ
передачи сообщений от демона.
5. Необходимо изменить текущий каталог на корневой. Если этого не
сделать, а текущий каталог, допустим, находится на примонтированной
файловой системе, последнюю нельзя будет размонтировать. Самым
надежным выбором является корневой каталог, всегда принадлежащий
корневой файловой системе.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Пример приложения демона на С++

Непрочитанное сообщение Olej » 25 ноя 2014, 17:24

Olej писал(а): Вот "демон по Робачевскому" ;-), (стр.181) :
Код примера демона от Робачевского, как это чаще всего и бывает в книгах, просто не компилируется в Linux ... не хватает нескольких #include ...

Но вот вам для начального приближения минимально правленный код, который проходит компиляцию:

Код: Выделить всё

[Olej@modules demonr]$ make
gcc -Wall -o demonr demonr.c
Его можно взять в качестве начального приближения для правок...
Вложения
demonr.c
(4.85 КБ) 271 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Пример приложения демона на С++

Непрочитанное сообщение Olej » 25 ноя 2014, 17:27

Olej писал(а): Но вот вам для начального приближения минимально правленный код, который проходит компиляцию:

Код: Выделить всё

[Olej@modules demonr]$ make
gcc -Wall -o demonr demonr.c
Его можно взять в качестве начального приближения для правок...
А вот вас компиляция того же кода в C++ ... которую можно назвать "демоном на C++" ;-) :

Код: Выделить всё

[Olej@modules demonr]$ g++ -Wall -o demonr_cc demonr.c
demonr.c: В функции «int main(int, char**)»:
demonr.c:54:27: предупреждение: сравнение знакового и беззнакового целых выражений [-Wsign-compare]
    for( fd = 0; fd < flim.rlim_max; fd++)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Пример приложения демона на С++

Непрочитанное сообщение Olej » 25 ноя 2014, 19:50

Olej писал(а): Вот "демон по Робачевскому" ;-), (стр.181) :
А вот "демон по Стивенсу" (стр.506) :
При программировании демонов во избежание нежелательных взаимодейст-
вий следует придерживаться определенных правил. Сначала мы перечислим
эти правила, а затем продемонстрируем функцию daemonize, которая их
реализует.
1. Прежде всего нужно вызвать функцию umask, чтобы сбросить маску режи-
ма создания файлов в значение 0. Маска режима создания файлов, насле-
дуемая от запускающего процесса, может маскировать некоторые биты
прав доступа. Если предполагается, что процесс-демон будет создавать
файлы, может потребоваться установка определенных битов прав доступа.
Например, если демон создает файлы с правом на чтение и на запись для
группы, маска режима создания файла, которая выключает любой из этих
битов, воспрепятствовала бы этому.
2. Вызвать функцию fork и завершить родительский процесс. Для чего это
делается? Во-первых, если демон был запущен как обычная команда обо-
лочки, то завершив родительский процесс, мы заставим командную оболочку
думать, что команда была выполнена. Во-вторых, дочерний процесс
наследует идентификатор группы процессов от родителя, но получает свой
идентификатор процесса; таким образом мы гарантируем, что дочерний
процесс не будет являться лидером группы, а это необходимое условие для
вызова функции setsid, который будет произведен далее.
3. Создать новую сессию, обратившись к функции setsid. При этом (вспомните
раздел 9.5) процесс становится (а) лидером новой сессии, (б) лидером новой
группы процессов и (в) лишается управляющего терминала.
4. Сделать корневой каталог текущим рабочим каталогом. Текущий рабо
чий каталог, унаследованный от родительского процесса, может нахо
диться на смонтированной файловой системе. Поскольку демон, как пра
вило, существует все время, пока система не будет перезагружена, то в по
добной ситуации, когда рабочий каталог демона находится в смонтиро
ванной файловой системе, ее невозможно будет отмонтировать.
Как вариант,' некоторые демоны могут устанавливать собственный теку-
щий рабочий каталог, в котором они производят все необходимые дейст-
вия. Например, демоны печати в качестве текущего рабочего каталога
часто выбирают буферный каталог, куда помещаются задания для печати.
5. Закрыть все ненужные файловые дескрипторы. Это предотвращает удер-
жание в открытом состоянии некоторых дескрипторов, унаследованных от
родительского процесса (командной оболочки или другого процесса). С по-
мощью нашей функции open_max (листинг 2.4) или с помощью функции get
rlimit (раздел 7.11) можно определить максимально возможный номер
дескриптора и закрыть все дескрипторы вплоть до этого номера.
6. Некоторые демоны открывают файловые дескрипторы с номерами 0,1 и 2 на
устройстве /dev/null - таким образом, любые библиотечные функции, которые
пытаются читать со стандартного устройства ввода или писать на
стандартное устройство вывода или сообщений об ошибках, не будут ока-
зывать никакого влияния. Поскольку демон не связан ни с одним терми-
нальным устройством, он не сможет взаимодействовать с пользователем
в интерактивном режиме. Даже если демон изначально был запущен в
рамках интерактивной сессии, он все равно переходит в фоновый режим, и
начальная сессия может завершиться без воздействия на процесс-демон. С
этого же терминала в систему могут входить другие пользователи, и демон
не должен выводить какую-либо информацию на терминал, да и поль-
зователи не ждут того, что их ввод с терминала будет прочитан демоном.
Видно, что это расширено и детализировано ... но, в принципе, то же самое.

К сожалению, в предисловии книги У. Ричард Стивенс, Стивен Раго (2-е издание, 2005г.) указано, что архив кодов к книге размещён на сервере ftp://ftp.uu.net/ (и далее URL). На настоящее время такого сервера не существует. И архив я показал только тот, который был к книге У. Ричард Стивенс (1-е издание, 1992г.). Но там нет, в чистом виде, примера к главе 13. Но это легко восполнить.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Пример приложения демона на С++

Непрочитанное сообщение Olej » 26 ноя 2014, 01:22

Olej писал(а): К сожалению, в предисловии книги У. Ричард Стивенс, Стивен Раго (2-е издание, 2005г.) указано, что архив кодов к книге размещён на сервере ftp://ftp.uu.net/ (и далее URL). На настоящее время такого сервера не существует. И архив я показал только тот, который был к книге У. Ричард Стивенс (1-е издание, 1992г.). Но там нет, в чистом виде, примера к главе 13. Но это легко восполнить.
Не так и легко ;-) ... потому что исходники из книги не собираются.
Но вот модифицированный проект, который вполне собирается и может служить начальным приближением.

Код: Выделить всё

[Olej@modules daemons]$ make
gcc -Wall demonsig.c already_running.c daemonize.c  -o demonsig
gcc -Wall -l pthread demonthr.c already_running.c daemonize.c  -o demonthr
Вложения
daemons.tgz
(3.04 КБ) 249 скачиваний

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 11 гостей