|
|
|
@ -23,33 +23,58 @@ |
|
|
|
#include <stdio.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <support/check.h> |
|
|
|
#include <support/support.h> |
|
|
|
#include <time.h> |
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
struct delayed_exit_request |
|
|
|
{ |
|
|
|
void (*exitfunc) (int); |
|
|
|
int seconds; |
|
|
|
}; |
|
|
|
|
|
|
|
static void * |
|
|
|
delayed_exit_thread (void *seconds_as_ptr) |
|
|
|
delayed_exit_thread (void *closure) |
|
|
|
{ |
|
|
|
int seconds = (uintptr_t) seconds_as_ptr; |
|
|
|
struct timespec delay = { seconds, 0 }; |
|
|
|
struct delayed_exit_request *request = closure; |
|
|
|
void (*exitfunc) (int) = request->exitfunc; |
|
|
|
struct timespec delay = { request->seconds, 0 }; |
|
|
|
struct timespec remaining = { 0 }; |
|
|
|
free (request); |
|
|
|
|
|
|
|
if (nanosleep (&delay, &remaining) != 0) |
|
|
|
FAIL_EXIT1 ("nanosleep: %m"); |
|
|
|
/* Exit the process successfully. */ |
|
|
|
exit (0); |
|
|
|
exitfunc (0); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
delayed_exit (int seconds) |
|
|
|
static void |
|
|
|
delayed_exit_1 (int seconds, void (*exitfunc) (int)) |
|
|
|
{ |
|
|
|
/* Create the new thread with all signals blocked. */ |
|
|
|
sigset_t all_blocked; |
|
|
|
sigfillset (&all_blocked); |
|
|
|
sigset_t old_set; |
|
|
|
xpthread_sigmask (SIG_SETMASK, &all_blocked, &old_set); |
|
|
|
struct delayed_exit_request *request = xmalloc (sizeof (*request)); |
|
|
|
request->seconds = seconds; |
|
|
|
request->exitfunc = exitfunc; |
|
|
|
/* Create a detached thread. */ |
|
|
|
pthread_t thr = xpthread_create |
|
|
|
(NULL, delayed_exit_thread, (void *) (uintptr_t) seconds); |
|
|
|
pthread_t thr = xpthread_create (NULL, delayed_exit_thread, request); |
|
|
|
xpthread_detach (thr); |
|
|
|
/* Restore the original signal mask. */ |
|
|
|
xpthread_sigmask (SIG_SETMASK, &old_set, NULL); |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
delayed_exit (int seconds) |
|
|
|
{ |
|
|
|
delayed_exit_1 (seconds, exit); |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
delayed__exit (int seconds) |
|
|
|
{ |
|
|
|
delayed_exit_1 (seconds, _exit); |
|
|
|
} |
|
|
|
|