The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Как послать сигнал дочернему процессу при смерти родительского?, !*! David, 21-Янв-02, 00:22  [смотреть все]
Мне надо запустить два процесса, которые следили бы друг за другом, т.е. если один из них каким-нибудь образом убивается (сигнал KILL или STOP), то второй его должен перезапустить. Один другого создаёт с помощью fork().
Как сделать, чтобы родитель перезапускал дочерний это очевидно - обрабатываем SIGCHLD, а вот как сделать, чтобы дочерний процесс мгновенно (с помощью сигнала) узнал о смерти родителя - этого не знаю. Я знаю, что дочернему процессу изначально не посылается никаких сигналов при смерти родительского.
Меня интересует: можно ли изменить ситуацию, т.е. сделать так, чтобы при килянии злоумышленниками родителя посылался заданный (неважно какой, но не KILL и не STOP) сигнал дочернему процессу?
Заранее спасибо.
  • 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.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру