- RE: Как послать сигнал дочернему процессу при смерти родительского?, Soldier, 11:54 , 21-Янв-02 (1)
> Мне надо запустить два процесса, >которые следили бы друг за >другом, т.е. если один из >них каким-нибудь образом убивается (сигнал >KILL или STOP), то второй >его должен перезапустить. Один другого >создаёт с помощью fork(). >Как сделать, чтобы родитель перезапускал дочерний >это очевидно - обрабатываем SIGCHLD, >а вот как сделать, чтобы >дочерний процесс мгновенно (с помощью >сигнала) узнал о смерти родителя >- этого не знаю. Я >знаю, что дочернему процессу изначально >не посылается никаких сигналов при >смерти родительского. >Меня интересует: можно ли изменить ситуацию, >т.е. сделать так, чтобы при >килянии злоумышленниками родителя посылался заданный >(неважно какой, но не KILL >и не STOP) сигнал дочернему >процессу? > Заранее спасибо. Signal KILL ne perehvativaetsya, poetomu esli roditel' poluchit etot signal, to on srazu pomret i nikogo predupredit' ob etom ne smozhet. Mozhno naprimer v ditenke pereodicheski vizivat' getppid() - raz v 5-10 sekund skazhem (ne putat' s getpid()!!!). Kak tol'ko parent otvalil, on vmesto PID parenta budet vozvrashat' 1 (PID init-a)
- RE: Как послать сигнал дочернему процессу при смерти родительского?, David, 03:11 , 24-Янв-02 (2)
Спасибо, конечно. Но этот вариант я знаю и хочется его избежать, если возможно. Так что если есть ещё предложения, то буду признателен. Даже не обязательно сигналами (но желательно), но мне надо, чтобы дочерний процесс узнал о смерти родителя МГНОВЕННО, а не через несколько секунд.
- RE: Как послать сигнал дочернему процессу при смерти родительского?, BartSimpson, 08:32 , 24-Янв-02 (3)
>Спасибо, конечно. Но этот вариант я >знаю и хочется его избежать, >если возможно. Так что если >есть ещё предложения, то буду >признателен. Даже не обязательно сигналами >(но желательно), но мне надо, >чтобы дочерний процесс узнал о >смерти родителя МГНОВЕННО, а не >через несколько секунд. Сразу предупреждаю, пьян внуль, но вот что пришло, в родительком создавай файл, в детище удаляй, если его нет, значимт, ну вобщем ты понял, извени если дрянь.
- RE: Как послать сигнал дочернему процессу при смерти родительского?, Soldier, 09:02 , 25-Янв-02 (5)
>Спасибо, конечно. Но этот вариант я >знаю и хочется его избежать, >если возможно. Так что если >есть ещё предложения, то буду >признателен. Даже не обязательно сигналами >(но желательно), но мне надо, >чтобы дочерний процесс узнал о >смерти родителя МГНОВЕННО, а не >через несколько секунд. Tak zapuskayte getppid() v tsikle bez vsyakih zaderzhek, kakie problemi? while(1) { if (getppid()==1) Parent_Pomer(); } Ya predlozhil proverku kazhdie 5-10 sekund tol'ko chtobi pomen'she gruzit' proc. V lyubom sluchae nado chto-to proveryat' - hot' trubu, hot' nalichie faila.
- RE: Как послать сигнал дочернему процессу при смерти родительского?, Арлекин, 12:58 , 24-Янв-02 (4)
Есть такая мысль: Сделай pipe между ними ( от предка ), и select'ом из дитяти проверяй его. Как только родитель отрубится труба, по идее, должна захлопнуться.
- Спасибо всем, David, 14:14 , 25-Янв-02 (6)
Спасибо большое за участие. Но все эти варианты я знаю. Задача состояла в том, чтобы сказать как-нибудь системе, чтобы она послала заданный сигнал дочернему процессу. По-моему, я даже читал где-то, что это можно сделать, но не могу найти. Мне нельзя грузить камень, т.к. прога будет запускаться у хостеров (а это им точно не понравится). В общем буду искать принципиально другие пути (просто я пока не изучил другие способы межпроцессного взаимодействия в UNIX). Кстати, кто-нибудь что-нибудь знает про функцию _atexit(). Мне её посоветовали, но не объяснили, что она делает. Ещё раз спасибо.
- RE: Спасибо всем, Арлекин, 15:04 , 25-Янв-02 (7)
Ковыряться некогда, но ЭТО работает (solaris 26) как тебе надо ( киляем папу - дохнет дитя )#include <stdlib.h> #include <iostream.h> #include <stdio.h> #include <unistd.h> #include <signal.h> pid_t child; void killer() { kill( child, 9 ); } int main() { atexit(killer); // выполнить при окончании switch(( child=fork()) ) { case (pid_t)0: system( "sleep 600"); return 0; default: break; } system("sleep 600"); return 0; } Но сомневаюсь что убьется дите, если сделать после форка exec.
- RE: Спасибо всем, CeroZewl, 18:34 , 26-Янв-02 (8)
э... пипец. я не оригинален, но все же -- man rulez.The atexit() function registers the given function to be called at pro- gram exit, whether via exit(3) or via return from the program's main. если, к примеру, "зашибить" прогу через abort() то atexit не поможет. кроме того, если дитенок сделает exec или еще что-нибудь этакое.. если прочесть вопрос, то можно заметить, что речь шла о перезапуске папы. а не убийстве дитенка при смерти папашы. think! (c) IBM. автору вопроса: изучи прежде способы IPC. тогда все будет прощее.
- RE: Спасибо всем, Арлекин, 12:43 , 27-Янв-02 (9)
Никто не спорит насчет того что НАПИСАНО в мане. Только ты запусти тот примерчик ( повторяю -Solaris 2.6 ) и убей папу kill -9. Посмотри на результат. Ман - он рулит ессно. Только пишут маны всёравно индусы или китайцы. Ты никогда не пытался разобраться в соляркиных драйверах с помощью 9й секции манов ? Успехов в безнадежном деле. ПРОВЕРЯТЬ НАДО. Это первое. Наконец, если есть желание застраховаться на все случаи жизни - делай по типу HPOV - собственный стартер/финишер/диспетчер. Хотя и тут МОЖНО найти дырку.... завязываю...
- RE: Спасибо всем, Soldier, 13:32 , 27-Янв-02 (10)
>Никто не спорит насчет того что >НАПИСАНО в мане. Только ты >запусти тот примерчик ( повторяю >-Solaris 2.6 ) и убей >папу kill -9. Посмотри на >результат. Ман - он рулит >ессно. Только пишут маны всёравно >индусы или китайцы. Ты никогда >не пытался разобраться в соляркиных >драйверах с помощью 9й секции >манов ? Успехов в безнадежном >деле. ПРОВЕРЯТЬ НАДО. Это первое. Ne znayu kak naschet Solaris 2.6, no v Linux-e atexit srabotaet tol'ko pri noramal'nom zavershenii progi (komandoy exit ili return). Esli proga viletela po signalu ili abort-u, to atexit ne otrabativaet. Kstatti v Linux est' starter-finisher-dispetcher - start-stop-daemon
- RE: Спасибо всем, Арлекин, 19:29 , 27-Янв-02 (11)
Именно ! В каждом *ксе такие приблуды ведут себя по-разному. Более того - автору кто-то предлагал юзать _atexit - в солярке такого нет, как и нет ^^ заранее созданого старт/стопа... Могу завтра проверить и под 8й соляркой, если кому интересно. Ни фрей ни линухов под руками нету. А вообще, тому кто придумал этот ход (atexit) видимо что-то мешало предусмотреть оба пути завершения.ЗЫЖ Предлагаю закончить тред и оставить решение проблемы исполнителю, т.к. универсального и всеприемлемого средства мы не найдём.
- RE: Спасибо всем, HeroZoul, 16:59 , 28-Янв-02 (14)
>Никто не спорит насчет того что >НАПИСАНО в мане. Только ты >запусти тот примерчик ( повторяю >-Solaris 2.6 ) и убей >папу kill -9. Посмотри на >результат. Ман - он рулит >ессно. Только пишут маны всёравно >индусы или китайцы.atexit -- C rtl. и то, что написано в man есть стандарт, не потому, что в man написано, а потому, что есть стандарт на C rtl. и именно с него написан man. > Ты никогда >не пытался разобраться в соляркиных юзал (Free|Open|Net)BSD(i), Linux и везде atexit работает так, как должен. а то, что в solaris не так, мне пофик. если на самом деле не так, значит solaris погань. вот и все. :) >драйверах с помощью 9й секции >манов ? Успехов в безнадежном >деле. ПРОВЕРЯТЬ НАДО. Это первое. ПРОВЕРЕНО. ЭЛЕКТРОНИКОЙ. :)
- RE: Спасибо всем, Арлекин, 19:10 , 28-Янв-02 (17)
>мне пофик. >если на самом деле не так, значит solaris >погань. вот и все. :) А мне уж тем более пфиГ как оно работает НЕ в солярке - я свои деньги зарабатываю написанием софта исключительно ПОД СОЛЯРИС. А погань или супер другие ОСи мне глубоко ДО... Не пофиГ должно быть тому, кто ДЕЛАЕТ софт с претензиями на переносимость. Тут уже ни электроника ни электроники не помогут.
- RE: Спасибо всем, ZuroCill, 14:29 , 29-Янв-02 (22)
>>мне пофик. >>если на самом деле не так, значит solaris >>погань. вот и все. :) >А мне уж тем более пфиГ >как оно работает НЕ в >солярке - я свои деньги >зарабатываю написанием софта исключительно ПОД >СОЛЯРИС. А погань или супер >другие ОСи мне глубоко ДО... > >Не пофиГ должно быть тому, кто >ДЕЛАЕТ софт с претензиями на >переносимость. Тут уже ни электроника >ни электроники не помогут. что я могу тебе ответить, Арле? ты не профи, и, следовательно, не авторитет для меня, ни в коей мере, это раз. ну а во-вторых, кто-то и в Чечне деньге делает.
- RE: Спасибо всем, Арлекин, 19:21 , 28-Янв-02 (18)
А под 8-й ( собрана ГНУтым )работает как положено. Вывод один - СПАРКовский (4.1) компилер в очередном месте не соответствует стандарту. Нету гнутого на 6-ке :-/ - не проверю.
- Все просто :-)), DDKJ_MIXZZZ, 07:19 , 28-Янв-02 (12)
Все довольно просто, к примеру, parent_process: после обработки все что ему нужно, открывает сокет и висит на каком то порту. После socket_accept он ничего не пишет в порт а вызывет sys_pause таким образом, тот кто решился читать с этого порта - висит пока что этот нашь parent_process работает. Дальше.... child_process: перехватывает у себя сигнал какойнить SOME_SIG. Создает от себя процесс. child_(child_process): этот процесс как раз и коннектится, к порту сокет которого открыл самый первый parent_process. После коннекта он пытается читать и ессно повисает так как parent_process а висит так как sys_pause. и короче вот этот процесс(child_(child_process)) выполняет sys_read и мля висит ;-)) и "развиснет" он тока после того как умрёт parent_process, поэтому следующей ф-цией после sys_read должна быть sys_kill(child_process,SOME_SIG); теперь когда умрет parent_process, обработчик сигнала SOME_SIG в child_process запустится моментально, и там уже можно делать все что угодно зная точно что parent умер. Все просто ;-)))
- RE: Все просто :-)), Soldier, 12:00 , 28-Янв-02 (13)
>Все довольно просто, к примеру, > >parent_process: > после обработки все что ему >нужно, > открывает сокет и висит на >каком то > порту. После socket_accept > он ничего не пишет в >порт > а вызывет sys_pause > таким образом, тот кто решился >читать > с этого порта - висит >пока что > этот нашь parent_process работает. > Дальше.... > >child_process: > перехватывает у себя сигнал > какойнить SOME_SIG. > Создает от себя процесс. >child_(child_process): > этот процесс как раз и >коннектится, к > порту сокет которого открыл > самый первый parent_process. > После коннекта он пытается читать > > и ессно повисает так как > > parent_process а висит так как > > sys_pause. > и короче вот этот процесс(child_(child_process)) > > выполняет sys_read и мля висит >;-)) > и "развиснет" он тока после >того как > умрёт parent_process, поэтому > следующей ф-цией после sys_read > должна быть sys_kill(child_process,SOME_SIG); > теперь когда умрет parent_process, > обработчик сигнала SOME_SIG в child_process > > запустится моментально, и там уже >можно > делать все что угодно зная >точно что parent > умер. > Все просто ;-))) I v kakom meste eto prosche (ili hotya bi luchshe) chem ispolz'ovanie getppid()? (Chistoe lyubopitsvo i nikakogo sarkazma).
- RE: Все просто :-)), DDKJ_MIXZZZ, 17:31 , 28-Янв-02 (15)
Просто человеку не нравятся циклы :-) не нравится ему for(;;) getppid(); :-) что я могу сделать ? :-) придумать для него что-то другое что может быть и устроит его, но на самом деле максимально быстро мне кажется циклом узнать нельзя, этож цикл, но это только мое мнение.
- RE: Все просто :-)), Арлекин, 19:00 , 28-Янв-02 (16)
Всё ниже ИМХО. В принципе и правильно, что не нравятся. В НОРМАЛЬНЫХ условиях вероятность преднамеренного убийства родителя БЕЗ НЕОБХОДИМОСТИ не так уж и велика, а такой цикл кроме того что будет по полной программе жрать ресурсы процессора ничем особым не полезен. Что до НЕнормальных условий - мне тяжело представить себе софт ( тем более промышленный ) кроме хакерского, которому нужна подобного рода функциональность, ибо еще ТОТ вопрос - а имеет ли смысл подымать папу незная причину смерти ??? Можно найти массу причин, когда такое развитие событий просто вредно. Представьте себе админа, которому при необходимости свалить задачу придется килять три-четыре процесса - хоть init 6 сразу делай.ЗЫЖ Дело его, конечно, но БабаЯга против :-)
- Спасибо, я всё понял, все мне очень помогли., David, 21:32 , 28-Янв-02 (19)
В общем спасибо этому дому за гостеприимство. Я получил кучу информации и идей для размышления. Дальше я сам разберусь. Учиться, учиться и учиться... :))З.Ы.: На самом деле софт не хакерский (но и не промышленный), а очень даже мирный и полезный (к тому же в любом случае при большом желании админ всегда может вырубить процессы). Необходимость в подобной защите возникла, когда я обнаружил, что программа кем-то киляется, причем точно не админом, потому что после того, как я поставил игнорирование SIGTERM, этот НЕКТО не смог уже совершить свое грязное дело (а пытался), ну или вероятно там админы - ламеры :).
- RE: Все просто :-)), Soldier, 10:32 , 29-Янв-02 (20)
>Всё ниже ИМХО. >В принципе и правильно, что не >нравятся. В НОРМАЛЬНЫХ условиях вероятность >преднамеренного убийства родителя БЕЗ НЕОБХОДИМОСТИ >не так уж и велика, >а такой цикл кроме того >что будет по полной программе >жрать ресурсы процессора ничем особым >не полезен.Soglasen. Potomu ya i predlagal zaderzhku. V obschem prvereno - esli stavit' zaderzhku v 10^(-4) sekundi, to protsesornoe vremya budet 0.0.... . Nizhe fragment koda: switch(fork()) { case 0: while(getppid()!=1) usleep(100); //child if (fork()==0) execl("./parent","./parent",NULL); else return; case -1: return; //error default: break; } .........
Perezapuskaet parent-a prakticheski mgnovenno. I zhret 0% protsesornogo vremeni i ne "zasiraet"pamyat'. Ya ne govoryu chto eto "best idea", no po moemu IMHO etot metod samiy prostoy iz vseh predlozhennih dlya resheniya konkretnoy zadachi - zadachi perezapuska child-om parent-a. Edinstvennoe - posle pervogo perezapuska parent stanet rezidentom. No mne kazhetsya eto nesuschestvenno.
- А вот тогда другой вопрос:, David, 12:24 , 29-Янв-02 (21)
Спасибо еще раз, с этим я уже всё понял, уже точно сделаю. Но вот другой вопрос, наверное более простой (извиняюсь, если ламерский, просто я еще новичок в программировании под UNIX): Как определить (и возможно зарегистрировать) процесс и/или пользователя, который пытается кильнуть программу - например сигналом TERM?
- RE: А вот тогда другой вопрос:, Soldier, 16:04 , 29-Янв-02 (24)
>Спасибо еще раз, с этим я >уже всё понял, уже точно >сделаю. >Но вот другой вопрос, наверное более >простой (извиняюсь, если ламерский, просто >я еще новичок в программировании >под UNIX): >Как определить (и возможно зарегистрировать) процесс >и/или пользователя, который пытается кильнуть >программу - например сигналом TERM? >Nizhe primer kak poluchit' pid potsesa, poslavshego signal (krome signalov SIGKILL i SIGSTOP): //====================== #include <signal.h> #include <stdio.h> void my_action(int sig, siginfo_t *si, void * p) { printf("Got signal %i from pid=%i\n",si->si_signo,si->si_pid); } main() { struct sigaction act; act.sa_flags=SA_SIGINFO; act.sa_sigaction=my_action; sigemptyset(&act.sa_mask); sigaction(SIGTERM,&act,NULL); while(1) sleep(1); } //==============================
Detali v "man sigaction". Pro strukturu siginfo_t tam zhe.
|