Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linux fork - execl, the executed process becomes zombie

I'm trying to run twinkle command line from a child process. For example like this:

int hangup() {
write_on_display("line3", "            ");
write_on_display("hide_icon", "DIALTONE");
write_on_display("hide_icon", "BACKLIGHT");

int pid = fork();
if (pid == 0) {
    int res = execl("/usr/bin/twinkle", " ", "--immediate", "--cmd",
            "answerbye", (char *) NULL);
    _exit(0);
} else {
    perror("hangup");
    return 0;
}
return 1;
}

but twinkle becomes zombie:

10020 pts/1    Z+     0:00 [twinkle] <defunct>
10040 pts/1    Z+     0:00 [twinkle] <defunct>
10053 pts/1    Z+     0:00 [twinkle] <defunct>
10064 pts/1    Z+     0:00 [twinkle] <defunct>
10097 pts/1    Z+     0:00 [twinkle] <defunct>
10108 pts/1    Z+     0:00 [twinkle] <defunct>
10130 pts/1    Z+     0:00 [twinkle] <defunct>

I tried to set signal(SIGCHLD, SIG_IGN); but without success. Actually I think that the child process dies, before twinkle had finished.

Running twinkle from command line like:

twinkle --immediate --call 100

does not make zombie - twinkle closes properly. What I'm missing there?

like image 248
Bozho Avatar asked Dec 06 '12 15:12

Bozho


2 Answers

The parent process needs to call waitpid() with process id of the child. From the linked reference page:

All of these system calls are used to wait for state changes in a child of the calling process, and obtain information about the child whose state has changed. A state change is considered to be: the child terminated; the child was stopped by a signal; or the child was resumed by a signal. In the case of a terminated child, performing a wait allows the system to release the resources associated with the child; if a wait is not performed, then the terminated child remains in a "zombie" state (see NOTES below).

For example:

pid_t pid = fork();
if (0 == pid)
{
    /* Child process. */
}
else
{
    /* Parent process, wait for child to complete. */
    int status;
    waitpid(pid, &status, 0);
}
like image 85
hmjd Avatar answered Nov 02 '22 09:11

hmjd


Yes, but I need parent and child to work asynchronous.

Actually I found my mistake. So, if somebody have similar problem, with a signal handler function like this:

void catch_child(int sig_num)
{
    /* when we get here, we know there's a zombie child waiting */
    int child_status;

    wait(&child_status);

}

and signal(SIGCHLD, catch_child)

in the main() function everything works.

PP Here: is a very good explanation.

like image 34
Bozho Avatar answered Nov 02 '22 11:11

Bozho