I seem to have a vague memory that some facility in Linux exists that allows one to fork() a process in such a way that the child is automatically reaped by the system without a zombie being created. What is this mechanism? Or is my memory just wrong?
Asked
Active
Viewed 460 times
3
-
2From the [wait man page](https://linux.die.net/man/2/wait): A child that terminates, but has not been waited for becomes a "zombie"......If a parent process terminates, then its "zombie" children (if any) are adopted by init(8), which automatically performs a wait to remove the zombies. " – kaylum Oct 27 '16 at 00:02
-
1You could daemonize the child so it immediately loses its parent. – Kerrek SB Oct 27 '16 at 00:03
-
@kaylum Thanks. I know about zombies. I thought there was a way to fork() and not need to reap because you don't care about the child's return code and have the system auto reap the child so that a zombie isn't created. – Chimera Oct 27 '16 at 00:04
-
Wasn't clear from your question. But yes, @KerrekSB describes that. – kaylum Oct 27 '16 at 00:04
-
@KerrekSB Thank you. I thought there was a much simpler way. Perhaps my memory is wrong. I wonder if I'm thinking of some Glib function. – Chimera Oct 27 '16 at 00:05
-
1https://stackoverflow.com/questions/17015830 – user3386109 Oct 27 '16 at 00:07
-
@Chimera: Daemonizing is pretty damn simple. Don't know how much simpler you need it to be. – Kerrek SB Oct 27 '16 at 00:15
-
@KerrekSB Yes it's simple. I just thought I remembered a simpler way. As it turns out I was thinking of Glib's g_spawn_* methods. – Chimera Oct 27 '16 at 00:16
-
@Chimera: The benefit of that seems mainly that it hooks up the I/O with the new process for you, which can indeed be quite fiddly and tricky (and deadlock-prone). (But you don't usually do I/O with daemon processes.) – Kerrek SB Oct 27 '16 at 00:17
4 Answers
4
The portable way to do this is to double-fork:
pid = fork();
if (pid>0) {
int status;
while (waitpid(pid, &status, 0) && !WIFEXITED(status) && !WIFSIGNALED(status));
if (WIFSIGNALED(status) || WEXITSTATUS(status)) goto error;
} else if (!pid) {
pid = fork();
if (pid) _exit(pid<0);
else {
// do child work here
_exit(0);
}
} else goto error;

R.. GitHub STOP HELPING ICE
- 208,859
- 35
- 376
- 711
3
You can ignore SIGCHLD so it's doesn't create zombie ;)
signal(SIGCHLD, SIG_IGN);
doc here: http://man7.org/linux/man-pages/man2/sigaction.2.html

Stargateur
- 24,473
- 8
- 65
- 91
-
Thank you. Saw that as well. But I read that it's not supported in older Linux kernels? And of course I'm working on embedded Linux systems with very old kernels. – Chimera Oct 27 '16 at 15:24
-
@Chimera That is correct: it's not supported prior to `POSIX.1-2001`, which is aligned with the C99 (`ISO/IEC 9899:1999`). If you're using an older system, this will not work. – Cloud Dec 10 '16 at 23:11
-
@DevNull You **really** down vote this! It's not a wrong answer Omg http://meta.stackexchange.com/questions/157841/what-do-i-do-when-someone-deliberately-downvotes-many-of-my-answers. He never say in his question that he work with old kernels! – Stargateur Dec 11 '16 at 02:03
-
This isn't serial downvoting. I was curious why you so vehemently defended your critique of my answer the other day, despite being proven dead wrong, so I investigated other answers of yours because I was curious if you were spreading misinformation on SO: I was correct. Also, TC noted in a comment **just above this one** that he/she is using older kernels. – Cloud Dec 11 '16 at 02:33
0
This can also be done via prctl()
prctl(PR_SET_PDEATHSIG, SIGTERM);
The above line inserted in the child process can cause it's termination when the parent process is dead. This can also work when any sub-reapers die(after they parent the child process), and if you need it's actual parent's death to kill the child process, then store the parent's pid
before fork()
and check it in the child process.
if (getppid() != parent_pid_before_fork)
exit(1);

Chaitanya Tetali
- 394
- 2
- 11