Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Программирование под Unix/Linux > создание демона |
Автор: roman83 22.12.2006, 10:37 |
создание демона ну прочитал http://linuxportal.ru/entry.php/2361_0_3_0_C/ ...к сожалению не совсем понял....мне нужно чтобы эта програмка автоматически стартовала при запуске компьютера...а здесь как я понял просто процесс создается как в Linux сделать ананлог виндусовского сервиса??? |
Автор: block 22.12.2006, 11:24 |
Добавьте нужную вам команду в файл /etc/rc.d/rc.local: echo 'echo "TEST LOCAL START" >> /var/log/messages' >> /etc/rc.d/rc.local |
Автор: roman83 22.12.2006, 11:49 |
так...приверно про это тоже прочитал.....а вопрос такой....у меня SUSE linux...там короче не файл со скриптом, а папка где находятся линки(ярлыки) длоя запуска(по моему это идиотизм)....можнол ли как то сделать ссылку но с параметрами командной строки для передачи???....и кстати какой "свой" или рабочий каталог будет при запуске приложения подобным образом??? ...и кстати эта ссылка должна быть просто на исполняемый файл или как бы на демон??? Добавлено @ 12:01 да уж....чтото не совсем понятно, что это должна быть за ссылка....на исполняемый файл???....так не подвесит ли он у меня систему, т.к. он у меня естественно работает и работает, и управление не передает.....и интересно, проиниализированны ли уже к этому времени будут сетевые интерфейсы, а то у меня программа с них информацию тянет... Добавлено @ 12:03 ну и еще...наверное все таки должен быть демон....и если я не отключу(ну или отключу) вывод в стандартный вывод, то что проихойдет при попытке вывода???... |
Автор: strmaks 22.12.2006, 13:00 |
В целом все выглядит следующим образом. Программа (демон) запускается перехватывает все потокии ввода вывода (STDIN, STDOUT) и поток ошибок (STDERR) и либо перенаправляет все это добро в файли, либо же пишет их в сислог, если не перехватывать то при попытке чего либо вывести на STDOUT или STDERR это удет отображено на консоли из которой выполнялся запуск либо же на первом терминале. Сделать это можно либо внутри программы либо командой запуска. После старта нужно увести задачу в фон, для это либо программой делается форк и отрыв от текущей нити исполнения, при этом потомок становится основным демоном а родитель тихо мирно умирает. Либо же запустить его добавив в конце командной строки символ & что заставляет оболочку увести в фон твою задачу, но она будут находится там лишь до тех пор пока открыта твоя консоль. Линки (ярлычки ![]() |
Автор: MAKCim 22.12.2006, 14:16 | ||||||||||
в gentoo конечно удобнее (rc-update рулит), никто не спорит но называть то, что вы назвали, идиотизмом, тоже не стоит вполне все логично init переходит от одного уровня выполнения к другому и попутно запускает все что лежит в /etc/init.d/rc<уровень>.d
symbolic link содержит путь к файлу, если этот файл - исполняемый и для него предусмотрены входные параметры, то вызов его через ссылку = вызов его напрямую (вместе с возможными параметрами)
пишешь своего демона (допустим в итоге получил бинарник daemon) создаешь файл в /etc/init.d (например daemon-run) вида
далее
|
Автор: roman83 22.12.2006, 14:47 |
ну вроде все сделал по такому принципу.....вроде все работает...НО!!!.....когда его запускаешь их менеджера сервисов, то при запуске(хоть и запускается сразу) долго весит табличка о том что он запускается, а потом пишет что вернулся NIL хотя приложение запустилось и работает |
Автор: roman83 22.12.2006, 15:03 |
делал так pid_t pid, sid; pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0); sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); } if ((chdir("/work")) < 0) { exit(EXIT_FAILURE); } дальше воя программа которая естественно управление не возвращает вот скрипт : . /etc/rc.status rc_reset DAEMON_NAME=Test1 DAEMON_PATH=/work/..<mypath>./$DAEMON_NAME case "$1" in start) echo -n 'Starting !!!' startproc $DAEMON_PATH Test1_SID eth2 -ORBmaxGIOPVersion 1.0 -ORBInitRef NameService=corbaname::[email protected]:23456/NameService rc_status -v ;; stop) echo -n "Shutting down !!! " killproc -TERM $DAEMON_NAME rc_status -v ;; restart) $0 stop $0 start rc_status ;; try-restart) $0 status if test $? = 0; then $0 restart else rc_reset fi rc_status ;; force-reload) $0 stop; sleep 1 && $0 start rc_status ;; reload) echo -n "Reload service " killproc -HUP $DAEMON_NAME rc_status -v ;; status) echo -n "Checking " checkproc $DAEMON_NAME rc_status -v ;; *) echo "Usage: $0 {start|stop|try-restart|restart|force-reload|reload|status}" exit 1 esac rc_exit кстати где прочитать про этот скрипт язык, а то делаю все по образу и подобию , это как то не очень правильно |
Автор: bilbobagginz 22.12.2006, 22:36 | ||
man sh, или man bash ( или поковыряй интернет на тему bash tutorial ) насчёт инициализации систем вообще, на самом деле, тема несложная, но она не из программирования. SuSE - из систем использующих сл. идею, пришедшую из UNIX System 5. задача: инициализировать службы системы из режима пользователя. решение:
процесс init ( самый первый процесс уровня пользователя ) подцепляет этот профиль, запуская соответствующую папку скриптов. тем самым проводит инициализацию системы соответствующего режима. в системах SUSE, скрипты каждого режима кладутся в форме символьный ссылок с особым именем в /etc/rc.d/rc<номер режима>.d/ ( напр. rc4.d ) сами же скрипты кладутся в /etc/rc.d/ тот скрипт, который их запускает, передаёт каждому 1 аргумент. аргумент определяется по имени ссылки в /etc/rc.d/rcN.d/ там есть скрипты начинающиеся с S<2 цифры><название инициализационного скрипта>, напр. S08portmap циферки в названии ссылки определяют порядок запуска скриптов между собой. если циферки идентичные - инициализация произойдёт в алфавитном порядке. циферки идут от 01 до 99.
в современных системах есть утилитки автоматического добавления скрипта инициализации из /etc/rc.d в соответствующий каталог /etc/rc.d/rc*.d ( man chkconfig, в SUSE, man update-rc.d в Debian ) в конце концов, (в SuSE) для превращения программы в сервис, нужно создать скрипт в /etc/rc.d, который реагирует на аргументы start, stop ( как минимум, но обычно и : restart, reload etc. ) и потом создать ссылку в правильной папке режима запуска, желательно в самом скрипте указать от каких сервисов он зависит, чтобы порядковый номер сервиса был установлен утилиткой сервисов правильно. ( посмотри в другие сервисы из /etc/rc.d ) немного сумбурно, но если вчитаться, врубиться можно ![]() и есть доля логики. удачи. |
Автор: Dragon 22.12.2006, 23:48 | ||
Демон, это приложение которое делает следующие вещи: 1. Форкает себя 2. Записывает свой .pid файл для скриптов конфигурации 3. Берет новый ID сессии 4. Закрывает все потоки ввода-вывода 5. Делает себе chroot("/") - у демона нет рабочей папки, все пути - только абсолютные. Конфиги держит или в известном и гарантированно существующем месте, вроде /etc/<daemon>.conf - или путь к файлу предварительно вкомпилируется на этапе конфигурирования в Autoconf/Automake проекте. 6. Устанавливает ВСЕ обработчики сигналов - для release сборок перехватываются также SIGSEGV и SIGFPE - юзеров очень огорчает вид корок, посему лучше неопределенное сообщение в логе и дополнительная отладка в подходящих условиях, чем убеждение юзверей в том что это иногда случается ![]() ![]() Не стоит забывать про SIGHUP - он часто используется для перегрузки конфига, это удобно: killall -1 testd 7. Входит в главный цикл (обычный цикл со sleep() или accept() и т.п.) Вот шаблон "культурного" демона:
|
Автор: MAKCim 23.12.2006, 10:42 |
Dragon, SIGSEGV даже перехватывать не рекомендуется - он явно вызван ошибкой при работе с памятью, т. е велика вероятность того, дальнейшие действия зависят от незавершенной операцией над ней (памятью) кроме того использовать signal() - тоже уставревший способ, имхо, лучший способ - sigaction() |
Автор: kirjanov 23.12.2006, 11:58 |
sigaction() - да, эт точно, POSIX так рекомендует обрабатывать сигналы |
Автор: Dragon 23.12.2006, 18:45 |
signal()/sigaction() - не суть важно, в принципе. По поводу SIGSEGV, он может быть и не ошибкой при работе с памятью, а ошибкой при работе с юзером, который накарлякал kill -11 <pid> за что по голове ему надо бы, но... В общем, доверять ему мы не можем, корку генерировать в release конфигурациях тоже не стоит - посему мы перехватываем SIGSEGV, а т.к. сделать ничего не можем, логируемся и выходим, чтобы враг не восторжествовал ![]() По поводу безопасности работы с памятью в случае возникновения SIGSEGV... В общем так, мы могли бы просто ограничиться вызовом exit(EXIT_FAILURE), что безопасно по определению. Логирование может привести к проблемам, т.к. даже та константная строка вроде "SIGSEGV raised" может быть перебита, хоть это и маловероятно, т.к. статические переменные находятся по более ранним адресам в памяти, чем динамические. Хуже конечно, если будет уничтожена секция кода ![]() Ладно, на практике этого никогда не возникало, хотя вероятность циклических вызовов SIGSEGV конечно неприятна, но это не то, что не дает мне спать спокойно ![]() P.S. Некоторые функции, например mprotect() подразумевают выброс SIGSEGV даже в случае если "фактического" fault'а не было ![]() |
Автор: MAKCim 24.12.2006, 11:36 | ||
вот и я про то же а смысл перехвата для последующего вызова exit() я не вижу ну да ладно |
Автор: Dragon 24.12.2006, 18:37 |
Единственный смысл такого перехвата - это чтобы core файлы не появлялись в результате "unhandled signal/exception". |
Автор: zabivator 24.12.2006, 23:49 |
А не проще ли заюзать Qt Service? Сразу получаем службу для венды и демон для линя) |
Автор: MAKCim 25.12.2006, 10:48 |
zabivator, Зачем нам M$, если мы пишем демона и не более |
Автор: kirjanov 25.12.2006, 19:21 | ||
из OpenBSD CVS - вполне туториал ![]() |