waitpid + timeout
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
static pid_t fork_child(void)
{
int pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
}
if (pid == 0) {
puts("child: sleeping...");
sleep(10);
puts("child: exiting");
exit(0);
}
return pid;
}
int waitpid_timeout(pid_t pid, int mseconds)
{
sigset_t mask, orig_mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) {
perror("sigprocmask");
return 1;
}
else {
struct timespec timeout;
timeout.tv_sec = mseconds / 1000;
timeout.tv_nsec = ( mseconds % 1000 ) * 1000000;
do {
if (sigtimedwait(&mask, NULL, &timeout) < 0) {
if (errno == EINTR) {
/* Interrupted by a signal other than SIGCHLD. */
continue;
}
else if (errno == EAGAIN) {
printf("Timeout, killing child\n");
kill(pid, SIGKILL);
}
else {
perror("sigtimedwait");
return 1;
}
}
else puts("got child quit signal");
break;
} while (1);
if (waitpid(pid, NULL, 0) < 0) {
perror("waitpid");
return 1;
}
return 0;
}
}
int main(int argc, char *argv[])
{
pid_t pid = fork_child();
waitpid_timeout(pid, 15000);
return 0;
}