Как остановить демон?

327
26 ноября 2016, 19:05

У меня никак не получается остановить работу демона, что я и пытаюсь сделать с помощью параметра stop. Подскажите, как лучше это сделать? И почему exit(0) не помогает?

  int main(int argc, char* argv[]) {
        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("/")) < 0) {
                    exit(EXIT_FAILURE);
            } 
            //.....................
            //.....................
            //.....................
            //.....................
            if(strcmp(argv[i], "stop") == 0) {
            cout << "Packets are not sniffed.\n" << endl;
            exit(0);
        }
return 0;
}
Answer 1

Дело даже не в типи сигнала, который Вы посылаете, а в том, что Вы не понимаете, как это всё работает...

Вот что вы пишите:

pid = fork();
if (pid < 0) {
    exit(EXIT_FAILURE);
}
if (pid > 0) {
    exit(EXIT_SUCCESS);
}

Т.е. Ваша программа завершается и когда pid<0 и тогда, когда pid>0. Остаётся только одно значение - ноль. Но это означает, что мы находимся в ДОЧЕРНЕМ процессе! В результате, команда

kill(pid, SIGCONT);

посылает сигнал процессу с pid == 0. Это Вы о чём?! Если Ваш дочерний процесс хочет сделать харикири, то это делается с помощью exit(0);

Если же Вы хотите убить дочерний из родителя, то надо сигнал посылать в ветке, где pid > 0. А сигнал может быть, ну хоть, SIGINT... Это то же самое, сто нажать Ctrl/C.

Отвечаю на просьбу в комменте: " ответить на буквальный вопрос в заголовке".

Есть только ОДИН способ убить процесс - послать ему сигнал, который не может быть обработан. Процесс (любой) не может обработать сигнал, если он не создал обработчик этого сигнала, либо этот сигнал в принйипе не обрабатывается (-9).

Для того, что бы отправить сигнал процессу, необходимо знать его PID. А вот здесь возможно два варианта: 1) Вы знаете его PID потому, что сами его создали с помощью операции fork. 2) Этот процесс - правильно написанный демон и он честно положил в каталог /var/run свой pid-файл, в котором и записан его pid. При этом имя файла должно совпадать с именем запущенного демона и его легко понять.

Таким образом, Ваш дочерний процесс должен записать свой pid в pid-файл в каталоге /ar/run. А ваш процесс, который его убивает - должен прочитать этот файл, взять из него pid и вызвать kill() с этим pid-ом.

Вроде - всё...

Answer 2

Начнём с того, что вы вообще не разобрались в сути процессов. Если вы запускаете программу ещё раз, то порождается совершенно новый процесс, и разумеется, exit вызовет завершение именно этого нового процесса, а не того, который у вас запущен как демон. Как правило в программах, поддерживающих режим демона это делается следующим образом: PID процесса-демона сохраняется где-нибудь в общедоступном месте (/var/run, /tmp), а процесс запущенный с параметром --stop вычитывает PID процесса-демона, и делает ему kill с этим значением PID.

Answer 3

SIGCONT не может помочь в данном случае, потому что этот сигнал продолжает выполнение остановленного процесса, а если процесс уже выполняется, этот сигнал игнорируется.

READ ALSO
Shlobj.h актуален? [закрыто]

Shlobj.h актуален? [закрыто]

Здравствуйте! Пишу простой проводник и столкнулся с такой библиотекойВопрос такой: для написания проводника ею лучше пользоваться? И для...

186
Динамическое обновление терминала ubuntu

Динамическое обновление терминала ubuntu

Я вывожу значение постоянно обновляемой переменной в терминал в виде:

193
Динамический массив [закрыто]

Динамический массив [закрыто]

Во время первого запуска программы, количество автобусных остановок – 234, но я хочу затем поменять и посмотреть, как программа все посчитает

194
QT - PSQL Потеряна связь

QT - PSQL Потеряна связь

Здравствуйте, возникает проблема при обычном SELECT

233