linux fork - execl, the executed process becomes zombie
Asked Answered
S

2

5

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?

Syncopated answered 6/12, 2012 at 15:4 Comment(0)
B
7

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);
}
Berm answered 6/12, 2012 at 15:8 Comment(2)
Just a sidenote: IIRC, the code after execl will not be executed unless execl produces an error.Fatima
@Jite, correct. The exit(0); disappears if execl() is successful.Berm
S
4

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.

Syncopated answered 7/12, 2012 at 10:30 Comment(1)
That is a good idea to catch the "child process end" signal in the parent process, and to wait for it there. Does it really work?Ballentine

© 2022 - 2024 — McMap. All rights reserved.