Created
March 23, 2023 05:28
-
-
Save valpackett/d21448b77cc8c0d2d4502505b6114e5a to your computer and use it in GitHub Desktop.
FreeBSD reaper API demo
This file contains hidden or 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
#include <sys/procctl.h> | |
#include <sys/time.h> | |
#include <sys/resource.h> | |
#include <sysexits.h> | |
#include <err.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <unistd.h> | |
#include <signal.h> | |
int main() { | |
srandomdev(); | |
if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == -1) err(EX_OSERR, NULL); | |
printf("reaper: %d\n", getpid()); | |
pid_t one, two; | |
if ((one = fork()) == 0) { | |
printf(" one: %d\n", getpid()); | |
usleep(1000 * (random() % 1000 + 200)); | |
if ((one = fork()) == 0) { | |
printf(" one.child: %d\n", getpid()); | |
usleep(1000 * (random() % 1000 + 200)); | |
if ((one = fork()) == 0) { | |
printf(" one.child.child1: %d\n", getpid()); | |
while (true) { | |
printf(" one.child.child1 looping\n"); | |
usleep(1000 * 250); | |
} | |
} | |
usleep(1000 * (random() % 1000 + 200)); | |
if ((one = fork()) == 0) { | |
printf(" one.child.child2: %d\n", getpid()); | |
while (true) { | |
printf(" one.child.child2 looping\n"); | |
usleep(1000 * 250); | |
} | |
} | |
usleep(1000 * (random() % 1000 + 200)); | |
printf(" one.child: return\n"); | |
return 0; | |
} | |
printf(" one: return\n"); | |
return 0; | |
} | |
if ((two = fork()) == 0) { | |
printf(" two: %d\n", getpid()); | |
sleep(1); | |
if ((two = fork()) == 0) { | |
printf(" two.child: %d\n", getpid()); | |
while (true) { | |
printf(" two.child looping\n"); | |
sleep(1); | |
} | |
} | |
printf(" two: return\n"); | |
return 0; | |
} | |
int cnt = 0; | |
while (true) { | |
usleep(1000 * 500); | |
int status = -1; | |
struct rusage usage = {0}; | |
pid_t reaped = -1; | |
while ((reaped = wait3(&status, WNOHANG, &usage)) != 0 && reaped != -1) | |
printf("reaper: reaped %d\n", reaped); | |
struct procctl_reaper_pidinfo infos[10] = {0}; | |
struct procctl_reaper_pids inforeq = { .rp_count = 10, .rp_pids = infos }; | |
if (procctl(P_PID, getpid(), PROC_REAP_GETPIDS, &inforeq) == -1) err(EX_OSERR, NULL); | |
printf("reaper: children:\n"); | |
for (size_t i = 0; i < inforeq.rp_count; i++) | |
if (infos[i].pi_pid != 0) | |
printf("- pid %d of subtree %d\n", infos[i].pi_pid, infos[i].pi_subtree); | |
struct procctl_reaper_kill killreq = { | |
.rk_sig = SIGTERM, | |
.rk_flags = REAPER_KILL_SUBTREE, | |
.rk_subtree = one, | |
.rk_killed = -1, | |
.rk_fpid = -1, | |
}; | |
cnt++; | |
if (cnt == 10) { | |
printf("reaper: killing one's descendants\n"); | |
if (procctl(P_PID, getpid(), PROC_REAP_KILL, &killreq) == -1) err(EX_OSERR, NULL); | |
printf("reaper: killed %d procs\n", killreq.rk_killed); | |
} | |
if (cnt == 15) { | |
printf("reaper: killing two's descendants\n"); | |
killreq.rk_subtree = two; | |
if (procctl(P_PID, getpid(), PROC_REAP_KILL, &killreq) == -1) err(EX_OSERR, NULL); | |
printf("reaper: killed %d procs\n", killreq.rk_killed); | |
} | |
if (cnt == 16) { | |
printf("reaper: done\n"); | |
return 0; | |
} | |
} | |
} |
This file contains hidden or 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
reaper: 30368 | |
one: 30369 | |
two: 30370 | |
one: return | |
one.child: 30371 | |
reaper: reaped 30369 | |
reaper: children: | |
- pid 30371 of subtree 30369 | |
- pid 30370 of subtree 30370 | |
one.child.child1: 30372 | |
one.child.child1 looping | |
two: return | |
two.child: 30373 | |
two.child looping | |
reaper: children: | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
- pid 30371 of subtree 30369 | |
- pid 30370 of subtree 30370 | |
one.child.child1 looping | |
one.child.child1 looping | |
reaper: reaped 30370 | |
reaper: children: | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
- pid 30371 of subtree 30369 | |
one.child.child2: 30374 | |
one.child.child2 looping | |
one.child.child1 looping | |
one.child.child2 looping | |
reaper: children: | |
- pid 30374 of subtree 30369 | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
- pid 30371 of subtree 30369 | |
one.child.child1 looping | |
two.child looping | |
one.child.child2 looping | |
one.child.child1 looping | |
one.child.child2 looping | |
reaper: children: | |
- pid 30374 of subtree 30369 | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
- pid 30371 of subtree 30369 | |
one.child.child1 looping | |
one.child.child2 looping | |
one.child.child1 looping | |
one.child: return | |
reaper: reaped 30371 | |
reaper: children: | |
- pid 30374 of subtree 30369 | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
two.child looping | |
one.child.child2 looping | |
one.child.child1 looping | |
one.child.child2 looping | |
one.child.child1 looping | |
reaper: children: | |
- pid 30374 of subtree 30369 | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
one.child.child2 looping | |
one.child.child1 looping | |
one.child.child2 looping | |
one.child.child1 looping | |
reaper: children: | |
- pid 30374 of subtree 30369 | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
two.child looping | |
one.child.child2 looping | |
one.child.child1 looping | |
one.child.child2 looping | |
one.child.child1 looping | |
reaper: children: | |
- pid 30374 of subtree 30369 | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
one.child.child2 looping | |
one.child.child1 looping | |
one.child.child2 looping | |
one.child.child1 looping | |
reaper: children: | |
- pid 30374 of subtree 30369 | |
- pid 30373 of subtree 30370 | |
- pid 30372 of subtree 30369 | |
reaper: killing one's descendants | |
reaper: killed 2 procs | |
two.child looping | |
reaper: reaped 30372 | |
reaper: reaped 30374 | |
reaper: children: | |
- pid 30373 of subtree 30370 | |
two.child looping | |
reaper: children: | |
- pid 30373 of subtree 30370 | |
reaper: children: | |
- pid 30373 of subtree 30370 | |
two.child looping | |
reaper: children: | |
- pid 30373 of subtree 30370 | |
reaper: children: | |
- pid 30373 of subtree 30370 | |
reaper: killing two's descendants | |
reaper: killed 1 procs | |
reaper: reaped 30373 | |
reaper: children: | |
reaper: done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment