1

I'm trying to launch a linux service from a c++ and I do it successfully but one of my process is marked as "defunct" and I don't want that my parent process dies.

My code is (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);
        }
    }
}

The exit of ps -e command is:

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

The /etc/init.d/zebra launches the service as daemon or something like that so I think this is the trick but:

Why there are 3 processes and one of them is marked as defunct? What is wrong in my code? How can I fix it?

Thanks in advance.

Chris
  • 327
  • 2
  • 6
  • 22
  • 1
    Fork twice: http://stackoverflow.com/questions/10932592/why-fork-twice, http://stackoverflow.com/questions/881388/what-is-the-reason-for-performing-a-double-fork-when-creating-a-daemon, http://en.wikipedia.org/wiki/Wait_(system_call) –  May 07 '14 at 15:04

2 Answers2

1

To remove zombies you the parent process must wait() its child or dies. If you need to make a non blocking wait() look at waitpid() with W_NOHANG flag.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • Hi Jean-Baptiste, I can't use wait or waitpid because the PID of the process becomes invalid, these processes are zombies so they are finished, their PID does not exists. – Chris May 08 '14 at 06:23
  • The process has a PID at some point - even if only briefly - and one of the reasons it becomes a zombie is that it has no parent (and some other stuff). The default behaviour for a process that is otherwise set up ok but doesn't have a parent is for 'init' to take ownership so that it doesn't become a zombie. – rivimey May 08 '14 at 10:45
  • No zombies have PID! This is exactly why they exist, they are a simple trace of their past existence. Anyway, if you don't know the PID (because you forget it), then you can make an "anonymous" wait, with `wait(NULL);`. – Jean-Baptiste Yunès May 09 '14 at 13:09
0

Correctly forking a daemon process is hard in Unix and Linux because there are a lot of details to get right, and order is also important. I would suspect a combination of open file descriptors and not detatching the controlling terminal, in this case.

I would strongly suggest using a well-debugged implementation from another program - one of the reduced-functionality command line shells such as rsh or ksh may be a good choice, rather than trying to bake your own version.

rivimey
  • 921
  • 1
  • 7
  • 24
  • Thank you for your response rivimey, but unfortunately I need to implement my own version because contractual issues. I'm going to launch the services, using the "system" call, because I'm root always and I'm gonna to try catch the system errors with WIFSIGNALED, WTERMSIG and WTERMSIG – Chris May 08 '14 at 06:20
  • There are public domain shells out there too: 'pdksh' is I think one of them: they will be free of all legal constraints, I expect. You don't need to copy the code, but reviewing it will be constructive. – rivimey May 08 '14 at 10:46