Skip to content

Instantly share code, notes, and snippets.

@eatnumber1
Created March 28, 2017 02:05

Revisions

  1. eatnumber1 created this gist Mar 28, 2017.
    72 changes: 72 additions & 0 deletions wait-with-timeout.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    #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;
    }