Skip to content

Instantly share code, notes, and snippets.

@cvengler
Created April 21, 2023 11:45
Show Gist options
  • Save cvengler/b4d0e4fc22e35b7b6d9756557b7b1067 to your computer and use it in GitHub Desktop.
Save cvengler/b4d0e4fc22e35b7b6d9756557b7b1067 to your computer and use it in GitHub Desktop.
signalfd(2) alongside waitpid(2)
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/signalfd.h>
#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void child(void);
static void parent(void);
static void fork_it(int);
static const int nchilds = 3000;
static pid_t childs[nchilds];
static void
child(void)
{
ptrace(PTRACE_TRACEME, 0, 0, 0);
raise(SIGSTOP);
sleep(5);
}
static void
fork_it(int n)
{
pid_t pid;
if (n == 0)
return;
switch ((pid = fork())) {
case -1:
err(1, "fork");
break;
case 0:
child();
_exit(0);
break;
default:
childs[n - 1] = pid;
fork_it(n - 1);
break;
}
}
static void
parent(void)
{
sigset_t mask;
int fd;
sigemptyset(&mask);
sigfillset(&mask);
sigprocmask(SIG_SETMASK, &mask, NULL);
if ((fd = signalfd(-1, &mask, 0)) == -1)
err(1, "signalfd");
while (1) {
struct signalfd_siginfo siginfo;
ssize_t n;
n = read(fd, &siginfo, sizeof(siginfo));
if (n != sizeof(siginfo))
err(1, "read");
printf("Got signal %d\n", siginfo.ssi_signo);
switch (siginfo.ssi_signo) {
case SIGINT:
case SIGTERM:
goto end;
break;
case SIGCHLD:
{
int status;
pid_t pid;
while (1) {
pid = waitpid(-1, &status, WNOHANG);
if (pid <= 0)
break;
if (WIFSTOPPED(status))
ptrace(PTRACE_CONT, pid, 0, 0);
}
}
break;
}
}
end:
puts("Parent begins to shutdown");
close(fd);
}
int
main(void)
{
fork_it(nchilds);
parent();
/* Kill the children */
{
int i;
for (i = 0; i < nchilds; ++i)
kill(childs[i], SIGKILL);
}
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment