-
-
Save zed/0b0a14fd8b436a04071d55e9b6f53bf4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Demonstrate that kill(pid, 0) == 0 for zombie processes. | |
$ make anton && ./anton | |
See https://ru.stackoverflow.com/q/725572/23044 | |
*/ | |
#include <assert.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <signal.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <unistd.h> | |
int main(void) | |
{ | |
pid_t pid = fork(); | |
if ( pid == 0) | |
{ | |
int pid = getpid(); | |
int ppid = getppid(); | |
printf("Child process: pid: %d \n", pid); | |
printf("Child process: ppid: %d \n", ppid); | |
int res = execvp("", NULL); | |
printf("Child process: res: %d \n", res); | |
_exit(72); | |
} | |
sleep(1); // allow the child to exit | |
printf("child pid: %d\n", pid); | |
{ // show zombie (<defunct>) | |
const char *format = "ps -ef | grep %d"; | |
const int n = snprintf(NULL, 0, format, pid); | |
assert(n > 0); | |
char command[n+1]; | |
int c = snprintf(command, n+1, format, pid); | |
assert(command[n] == '\0'); | |
assert(c == n); | |
system(command); | |
} | |
if ( kill(pid, 0) == 0 ) // zombie "exists" | |
{ | |
printf("kill returned 0 \n"); | |
} | |
else | |
{ | |
exit(EXIT_FAILURE); | |
} | |
{ // reap the child process | |
int status = 0; | |
if (waitpid(pid, &status, WNOHANG) && WIFEXITED(status)) | |
{ | |
printf("child exited with status %d\n", WEXITSTATUS(status)); | |
} | |
if ( kill(pid, 0) == 0 ) // can't be | |
{ | |
exit(EXIT_FAILURE); | |
} | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
"""Show that `kill(pid, 0)` is successful for zombies (no ESRCH).""" | |
from os import * | |
pid = fork() | |
if pid == 0: # child process | |
_exit(42) | |
# parent process | |
# wait until the child dies (becomes zombie) | |
while system(fr"ps -ef | grep {pid} | grep defunct\> >{devnull}"): | |
pass | |
kill(pid, 0) # no exception: zombie "exists" | |
w_pid, status = waitpid(-1, WNOHANG) # reap zombie | |
assert w_pid == pid and WIFEXITED(status) | |
assert WEXITSTATUS(status) == 42, status | |
try: | |
kill(pid, 0) | |
except ProcessLookupError: # errno.ESRCH | |
pass | |
else: | |
assert 0, "can't be" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment