Suppose a function "fun" can be blocked, and the its caller hope it will be returned back if "fun" is running too much long; in other words, "fun()" can be overwritten with "fun(int timeout)"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <assert.h>
#include <signal.h>
#include <setjmp.h>
sigjmp_buf run_with_timeout_env;
void
abort_run_with_timeout (int sig)
{
assert (sig == SIGALRM);
siglongjmp (run_with_timeout_env, -1);
}
void fun(int secs)
{
printf("[%d] sleep %d seconds, start.../n",time(NULL), secs);
sleep(secs);
printf("[%d] sleep %d seconds, end/n",time(NULL), secs);
}
int main(int argc, char* argv[])
{
signal (SIGALRM, abort_run_with_timeout);
if (sigsetjmp(run_with_timeout_env,1) != 0)
{
printf("[%d] here longjmp returned./n",time(NULL)); // "fun()" will be return in 2 seconds, so it must come here.
signal (SIGALRM, SIG_DFL);
return 1;
}
printf("[%d] start a 2 seconds alarm./n",time(NULL));
alarm (2); // a alarm signal will be invoked within 2 seconds.
printf("[%d] start calling user funcation./n",time(NULL));
fun(5); // this require the function "fun" will return in 5 seconds, as we know there is a 2-seconds alarm signl
printf("[%d] clear alarm./n",time(NULL));
alarm (0);
printf("[%d] restore signal function back./n",time(NULL));
signal (SIGALRM, SIG_DFL);
}
The program is compiled under Solaris 5.10, Sun Studio 11
#:cc alarm.c
#:./a.out
[1263108032] start a 2 seconds alarm.
[1263108032] start calling user funcation.
[1263108032] sleep 5 seconds, start...
[1263108034] here longjmp returned.