#define _BSD_SOURCE
#define _DEFAULT_SOURCE
#define _POSIX_C_SOURCE 200809L
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#ifndef __WNOTHREAD
#define __WNOTHREAD 0x20000000
#endif
static sigjmp_buf syd_jmpbuf;
static volatile sig_atomic_t syd_armed;
void handle_sig_ptrace(int sig)
{
(void)sig;
if (syd_armed) {
syd_armed = 0;
siglongjmp(syd_jmpbuf, 1);
}
}
int syd_safe_wait_all(siginfo_t *info, unsigned long cookie)
{
sigset_t mask;
long ret;
if (info == NULL)
return -EFAULT;
memset(info, 0, sizeof(*info));
sigemptyset(&mask);
sigaddset(&mask, SIGRTMIN);
if (sigsetjmp(syd_jmpbuf, 0) != 0) {
sigprocmask(SIG_BLOCK, &mask, NULL);
return (info->si_pid != 0);
}
syd_armed = 1;
sigprocmask(SIG_UNBLOCK, &mask, NULL);
ret = syscall(SYS_waitid, P_ALL, 0, info,
WEXITED | __WNOTHREAD, NULL, cookie);
syd_armed = 0;
sigprocmask(SIG_BLOCK, &mask, NULL);
if (ret < 0)
return -errno;
return (info->si_pid != 0) ? 1 : -EINTR;
}