Skip to content

Instantly share code, notes, and snippets.

@zed

zed/anton.c Secret

Last active October 2, 2017 11:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zed/0b0a14fd8b436a04071d55e9b6f53bf4 to your computer and use it in GitHub Desktop.
Save zed/0b0a14fd8b436a04071d55e9b6f53bf4 to your computer and use it in GitHub Desktop.
/** 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;
}
#!/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