Skip to content

Instantly share code, notes, and snippets.

@eatnumber1
Created March 28, 2017 02:05
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 eatnumber1/0b45f33e4d2ddec52f277460347945be to your computer and use it in GitHub Desktop.
Save eatnumber1/0b45f33e4d2ddec52f277460347945be to your computer and use it in GitHub Desktop.
wait(2) with timeout using a timer
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdbool.h>
#include <limits.h>
#include <sys/wait.h>
#include <errno.h>
void handler() {}
int main() {
pid_t tid = (pid_t) syscall(SYS_gettid);
int signum = SIGRTMIN + 4;
timer_t timerid;
struct sigevent event = {
.sigev_notify = SIGEV_THREAD_ID,
.sigev_signo = signum,
._sigev_un._tid = tid
};
if (timer_create(CLOCK_MONOTONIC, &event, &timerid) == -1) {
perror("timer_create");
exit(EXIT_FAILURE);
}
struct sigaction act = {
.sa_handler = handler
};
if (sigaction(signum, &act, NULL) == -1) {
perror("rt_sigaction");
exit(EXIT_FAILURE);
}
pid_t child_pid = fork();
if (child_pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (child_pid == 0) {
// child
while (true) sleep(UINT_MAX);
}
// parent
struct itimerspec timerspec = {
.it_value = {
.tv_sec = 3
}
};
if (timer_settime(timerid, 0, &timerspec, NULL) == -1) {
perror("timer_settime");
exit(EXIT_FAILURE);
}
int wstatus;
pid_t dead_child = wait(&wstatus);
if (dead_child == -1) {
if (errno != EINTR) {
perror("wait");
exit(EXIT_FAILURE);
}
} else {
fprintf(stderr, "wait exited successfully, returning %d\n", dead_child);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment