Запуск службы из С++ с помощью execv

Я пытаюсь запустить службу Linux из С++, и я делаю это успешно, но один из моих процессов помечен как «несуществующий», и я не хочу, чтобы мой родительский процесс умирал.

Мой код (testRip.cpp):

int main()
{
    char* zebraArg[2];
    zebraArg[0] = (char *)"zebra";
    zebraArg[1] = (char *)"restart";

    char* ripdArg[2];
    ripdArg[0] = (char *)"ripd";
    ripdArg[1] = (char *)"restart";

    pid_t ripPid;
    pid_t zebraPid;

    zebraPid = fork();
    if(zebraPid == 0)
    {
        int32_t iExecvRes = 0;
        iExecvRes = execv("/etc/init.d/zebra", zebraArg);
        return 0;

        if(iExecvRes == -1)
        {
        ::syslog((LOG_LOCAL0 | LOG_ERR),
            "zebra process failed \n");
        }
    }
    else
    {
        while(1)
        {
                ::syslog((LOG_LOCAL0 | LOG_ERR),
                 "running\n");
            sleep(2);
        }
    }
}

Выход команды ps -e:

9411 pts/1    00:00:00 testRip
9412 pts/1    00:00:00 testRip <defunct>
9433 ?        00:00:00 zebra

/etc/init.d/zebra запускает службу как демон или что-то в этом роде, поэтому я думаю, что это трюк, но:

Почему есть 3 процесса и один из них помечен как несуществующий? Что не так в моем коде? Как я могу это исправить?

Заранее спасибо.


person Chris    schedule 07.05.2014    source источник
comment


Ответы (2)


Правильно разветвить процесс демона сложно в Unix и Linux, потому что нужно правильно проработать много деталей, и порядок также важен. В данном случае я бы заподозрил комбинацию открытых файловых дескрипторов и отсутствие отключения управляющего терминала.

Я бы настоятельно рекомендовал использовать хорошо отлаженную реализацию из другой программы - одна из оболочек командной строки с ограниченной функциональностью, такая как rsh или ksh, может быть хорошим выбором, а не пытаться испечь свою собственную версию.

person rivimey    schedule 07.05.2014
comment
Спасибо за ответ, rivimey, но, к сожалению, мне нужно реализовать свою версию из-за проблем с договором. Я собираюсь запускать службы с помощью системного вызова, потому что я всегда root, и я собираюсь попытаться отловить системные ошибки с помощью WIFSIGNALED, WTERMSIG и WTERMSIG. - person Chris; 08.05.2014
comment
Существуют также общедоступные оболочки: 'pdksh', я думаю, одна из них: я ожидаю, что они будут свободны от всех юридических ограничений. Вам не нужно копировать код, но просмотр его будет конструктивным. - person rivimey; 08.05.2014

Чтобы удалить зомби, родительский процесс должен wait() его дочерний процесс или умереть. Если вам нужно сделать неблокирующий wait(), посмотрите на waitpid() с флагом W_NOHANG.

person Jean-Baptiste Yunès    schedule 07.05.2014
comment
Привет, Жан-Батист, я не могу использовать ожидание или ожидание, потому что PID процесса становится недействительным, эти процессы являются зомби, поэтому они завершены, их PID не существует. - person Chris; 08.05.2014
comment
В какой-то момент у процесса есть PID — пусть даже ненадолго — и одна из причин, по которой он становится зомби, заключается в том, что у него нет родителя (и некоторые другие вещи). Поведение по умолчанию для процесса, который в остальном настроен нормально, но не имеет родителя, заключается в том, что «init» становится владельцем, чтобы он не стал зомби. - person rivimey; 08.05.2014
comment
У зомби нет PID! Именно поэтому они существуют, они являются простым следом их прошлого существования. В любом случае, если вы не знаете PID (потому что забыли его), вы можете сделать анонимное ожидание с помощью wait(NULL);. - person Jean-Baptiste Yunès; 09.05.2014