So I'm trying to call an alarm to display a message "still working.." every second.
I included signal.h.
Outside of my main I have my function: (I never declare/define s for int s)
void display_message(int s); //Function for alarm set up
void display_message(int s) {
printf("copyit: Still working...\n" );
alarm(1); //for every second
signal(SIGALRM, display_message);
}
Then, in my main
while(1)
{
signal(SIGALRM, display_message);
alarm(1); //Alarm signal every second.
That's in there as soon as the loop begins. But the program never outputs the 'still working...' message. What am I doing incorrectly? Thank you, ver much appreciated.
Signal handlers are not supposed to contain "business logic" or make library calls such as printf. See C11 §7.1.4/4 and its footnote:
Thus, a signal handler cannot, in general, call standard library functions.
All the signal handler should do is set a flag to be acted upon by non-interrupt code, and unblock a waiting system call. This program runs correctly and does not risk crashing, even if some I/O or other functionality were added:
#include <signal.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
volatile sig_atomic_t print_flag = false;
void handle_alarm( int sig ) {
print_flag = true;
}
int main() {
signal( SIGALRM, handle_alarm ); // Install handler first,
alarm( 1 ); // before scheduling it to be called.
for (;;) {
sleep( 5 ); // Pretend to do something. Could also be read() or select().
if ( print_flag ) {
printf( "Hello\n" );
print_flag = false;
alarm( 1 ); // Reschedule.
}
}
}
Move the calls to signal and alarm to just before your loop. Calling alarm over and over at high speed keeps resetting the alarm to be in one second from that point, so you never reach the end of that second!
For example:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void display_message(int s) {
printf("copyit: Still working...\n" );
alarm(1); //for every second
signal(SIGALRM, display_message);
}
int main(void) {
signal(SIGALRM, display_message);
alarm(1);
int n = 0;
while (1) {
++n;
}
return 0;
}
Do not call alarm() twice, just call it once in main() to initiate the callback, then once in display_message().
Try this code on Linux (Debian 7.8) :
#include <stdio.h>
#include <signal.h>
void display_message(int s); //Function for alarm set up
void display_message(int s)
{
printf("copyit: Still working...\n" );
alarm(1); //for every second
signal(SIGALRM, display_message);
}
int main()
{
signal(SIGALRM, display_message);
alarm(1); // Initial timeout setting
while (1)
{
pause();
}
}
The result will be the following one :
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
The alarm() call is for a one off signal.
To repeat an alarm, you have to call alarm() again each time the signal occurs.
Another issue, also, is that you're likely to get EINTR errors. Many system functions get interrupted when you receive a signal. This makes for much more complicated programming since many of the OS functions are affected.
In any event, the correct way to wait for the next SIGALRM is to use the pause() function. Something the others have not mentioned (instead they have tight loops, ugly!)
That being said, what you are trying to do would be much easier with a simple sleep() call as in:
// print a message every second (simplified version)
for(;;)
{
printf("My Message\n");
sleep(1);
}
and such a loop could appear in a separate thread. Then you don't need a Unix signal to implement the feat.
Note: The sleep() function is actually implemented using the same timer as the alarm() and it is clearly mentioned that you should not mix both functions in the same code.
sleep(3) may be implemented using SIGALRM; mixing calls to alarm() and sleep(3) is a bad idea.
(From Linux man alarm)
void alarm_handler(int)
{
alarm(1); // recurring alarm
}
int main(int argc, char *argv[])
{
signal(SIGALRM, alarm_handler);
alarm(1);
for(;;)
{
printf("My Message\n");
// ...do other work here if needed...
pause();
}
// not reached (use Ctrl-C to exit)
return 0;
}
You can create variations. For example, if you want the first message to happen after 1 second instead of immediately, move the pause() before the printf().
The "other work" comment supposes that your other work does not take more than 1 second.
It is possible to get the alarm signal on a specific thread if work is required in parallel, however, this can be complicated if any other timers are required (i.e. you can't easily share the alarm() timer with other functions.)
P.S. as mentioned by others, doing your printf() inside the signal handler is not a good idea at all.
There is another version where the alarm() is reset inside main() and the first message appears after one second and the loop runs for 60 seconds (1 minute):
void alarm_handler(int)
{
}
int main(int argc, char *argv[])
{
signal(SIGALRM, alarm_handler);
for(int seconds(0); seconds < 60; ++seconds)
{
alarm(1);
// ...do other work here if needed...
pause();
printf("My Message\n");
}
// reached after 1 minute
return 0;
}
Note that with this method, the time when the message will be printed is going to be skewed. The time to print your message is added to the clock before you restart the alarm... so it is always going to be a little over 1 second between each call. The other loop is better in that respect but it still is skewed. For a perfect (much better) timer, the poll() function is much better as you can specify when to wake up next. poll() can be used just and only with a timer. My Snap library uses that capability (look for the run() function, near the bottom of the file). In 2019. I moved that one .cpp file to the eventdispatcher library. The run() function is in the communicator.cpp file.
POSIX permits certain of its functions to be called from signal handling context, the async-signal safe functions, search for "async-sgnal safe" here. (These may be understood as "system calls" rather than library calls). Notably, this includes write(2).
So you could do
void
display_message (int s) {
static char const working_message [] = "copyit: Still working...\n";
write (1, working_message, sizeof working_message - sizeof "");
alarm(1); /* for every second */
}
By the way, precise periodic alarms are better implemented using setitimer(2),
since these will not be subject to drift. Retriggering the alarm via software, as done here, will unavoidably accumulate error over time because of the time spent executing the software as well as scheduling latencies.
In POSIX sigaction(2) superceedes signal(2) for good reason:
the original Unix signal handling model was simple. In particular,
a signal handler was reset to its original "deposition" (e.g., terminate
the process) once it was fired. You would have to re-associate
SIGALRM with display_message() by calling signal() just before
calling alarm() in display_message().
An even more important reason for using sigaction(2) is the
SA_RESTART flag. Normally, system calls are interrupted when
a signal handler is invoked. I.e., when then signal handler returns,
the system call returns an error indication (often -1) and errno is
set to EINTR, interrupted system call. (One reason for this
is to be able to use SIGALRM to effect time outs, another is
to have a higher instance, such as a user, to "unblock" the
current process by sending it a signal, e.g.,
SIGINT by pressing control-C at the terminal).
In your case, you want signal handling to be transparent
to the rest of the code, so you would set the SA_RESTART flag
when invoking sigaction(2). This means the kernel should
restart the interrupted system call automatically.
ooga is correct that you keep reloading the alarm so that it will never go off. This works. I just put a sleep in here so you don't keep stepping on yourself in the loop but you might want to substitute something more useful depending on where you are headed with this.
void display_message(int s)
{
printf("copyit: Still working...\n" );
// alarm(1); //for every second
// signal(SIGALRM, display_message);
}
int main(int argc, char *argv[])
{
int ret;
while(1)
{
signal(SIGALRM, display_message);
alarm(1);
if ((ret = sleep(3)) != 0)
{
printf("sleep was interrupted by SIGALRM\n");
}
}
return (0);
}
Related
I implemented a timer for a Linux user-space application using an old fashion way.
int main(){
//do some things
signal(SIGALRM, do_things);
alarm(1);
while(1) {
//other things
}
}
void do_things()
{
tic++;//global variable
printf("time: %d...", tic);
if (tic%30 == 0) {
printf("hha\n ");
do_calculation();
}
alarm(1);
}
It runs random times and stop print out anything, The application still alive but my timer seems gone. I have no idea where should I start to check. Any suggestion is appreciated.
Edit: Did some googling, Signal handlers are not supposed to contain "business logic" or make library calls such as printf.
All the signal handler should do is set a flag to be acted upon by non-interrupt code.
Though I still don't know what really happens to cause message disappear..
i have an assignment to make, for university, it is almost done, most thing working, there is just one aspect that is not working and i'm not quite sure how to fix it..
The objetivo is to make the problem wait for 2 ctrl+C and close.. But if he catch a first ctrl+C and pass more then 3 seconds the program must forget about it and wait again for another 2 ctrl+C. This is how i'm doing it:
/*Problem 2. Write a program that sleeps forever until the user interrupts it twice with a Ctrl-C, and
then exits. Once the first interrupt is received, tell the user: “Interrupt again to exit.”. The first
interrupt should be forgotten 3 seconds after it has occurred. Additionally, the program should block
the SIGQUIT signal, and ignore the SIGTSTP signal. The program should start by printing “Interrupt
twice with Ctrl-C to quit.” on the screen.*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
//handler to catch the first ctrl_c and ask user to do it another time(no reference to time limit)
void ctrl_c(int sig){
signal(sig, SIG_IGN);
printf("\nInterrupt again to exit.\n");
}
//handler for second ctrl_c. If called, program will end
void second_catch(int sig){
if(sig == SIGINT){
printf("\n");
exit(0);
}
}
//handler to always ignore ctrl_z
void ctrl_z(int sig){
signal(sig, SIG_IGN);
}
int main(){
//blocking SIQUIT (Ctrl+\) using series of command to change the mask value of SIGQUIT
sigset_t sg;
sigemptyset (&sg);
sigaddset(&sg, SIGQUIT);
sigprocmask(SIG_BLOCK, &sg, NULL);
//installing handler to ignore SIGTSTP (Ctrl+Z)
signal(SIGTSTP, ctrl_z);
//two part SIGINT handling
printf("\nInterrupt twice with Ctrl+C to quit.\n");
signal(SIGINT, ctrl_c); //first handler install
do{ //cycle for second hanler install and 3 second timer
if(sleep(3) == 0){
main(); //if second_catch handler is not called within 3 seconds, program will restart
}
else {
signal(SIGINT, second_catch); //upon call, program will end
}
}while(1);
return 0;
}
What's happening is that it keeps reseting after 3 seconds, in a loop.. But i want to reset only 1 time after i click ctrl+c and 3 seconds passed..
What must i change?
Your approach is unlikely to lead to a working program.
First, use a signal handler that only sets a global variable (of volatile sig_atomic_t type) whenever a SIGINT signal is caught. Do not try to print anything from the signal handler, as standard I/O is not async-signal safe.
Second, use sigaction() to install the signal handler. Use zero flags. In other words, do NOT use SA_RESTART flag when installing the handler. This way, when a signal is delivered to your handler, it will interrupt most syscalls (including sleeps). (The functions will return -1 with errno == EINTR.)
This way, after your main() has installed the signal handler, you can have it print the instruction, and enter into a loop.
In the loop, clear the interrupt flag, and sleep for a few seconds. It does not matter how long. If the interrupt flag is not set after the sleep completes, continue (at the beginning of the loop).
Otherwise, you know that the user has pressed Ctrl+C. So, clear the interrupt flag, and sleep for another three seconds. If the flag is set after the sleep completes, you know the user supplied another Ctrl+C, and you can break out of the loop. Otherwise, you just continue the loop again.
Technically, there is a race condition here, as the user might press Ctrl+C twice in a row, rapidly enough so that the main() only sees one.
Unfortunately, increments (flag++) are not atomic; the compiler or the hardware may actually do temp = flag; temp = temp + 1; flag = temp; and the signal may be delivered just before the third step, leading to the signal handler and main() seeing different values of flag.
One way around that is to use C11 atomics (if the architecture and C library provides them, in <stdatomic.h>, with macro ATOMIC_INT_LOCK_FREE defined): volatile atomic_int flag; for the flag, __atomic_add_fetch(&flag, 1, __ATOMIC_SEQ_CST) to increment it, and __atomic_sub_fetch(&flag, 1, __ATOMIC_SEQ_CST) to decrement it.
Another way would be to use a POSIX semaphore. The signal handler can increment it (using sem_post()) safely. In main(), you can use sem_timedwait() to wait for the signal for a limited time, and sem_trywait() to decrement it.
A third way would be to use sigtimedwait() to catch the signal in main() with a timeout, without any signal handlers. This last one is, I believe, the most robust and simple to implement, so that's what I'd use in a real application.
It turns out that there is another way to achieve this, one that responds to two consecutive Ctrl+C presses within three seconds, without leaving any nasty corner cases.
This is NOT exactly what was asked of OP, and as such is not a valid answer to their exercise, but this would be a good approach otherwise.
The idea is to use alarm() and a SIGALRM handler, and two sig_atomic_t flags: one that counts the Ctrl+C keypresses, and one that flags the case when there have been two in a three-second period.
Unfortunately, sleep() cannot be used in this case -- you have to use nanosleep() instead --, as sleep(), alarm(), and SIGALRM signal handling may interfere with each other.
Essentially, we use
#define INTR_SECONDS 3
static volatile sig_atomic_t done = 0;
static volatile sig_atomic_t interrupted = 0;
static void handle_sigalrm(int signum)
{
if (interrupted > 1)
done = 1;
interrupted = 0;
}
static void handle_sigint(int signum)
{
interrupted++;
if (interrupted > 1) {
done = 1;
alarm(1);
} else
alarm(INTR_SECONDS);
}
handle_sigalrm() is installed as the SIGALRM handler, with SIGINT in its signal mask; handle_sigint() is installed as the SIGINT handler, with SIGALRM in its signal mask. This way the two signal handlers block each other, and won't be interrupted by each other.
When a first SIGINT is received, the alarm is primed. If this is the second (or third etc.) SIGINT without an intervening SIGALRM, we also set the done flag, and prime the alarm to occur in one second, to ensure we catch the state change in at most one second.
When a SIGALRM is received, the interrupt count is zeroed. If it was two or more, the done flag is also set.
In main(), we only check done and interrupted, never modify them. This avoids the corner cases I was worried about.
In the worst case, there is one second delay to quitting, if the second Ctrl+C is delivered after we check, but just before we sleep. The alarm(1) in handle_sigint() is for just that case.
The loop in main is then just
while (!done) {
while (!done && !interrupted)
nanosleep(&naptime, NULL);
if (done)
break;
printf("Ctrl+C again to quit!\n");
fflush(stdout);
while (interrupted == 1 && !done)
nanosleep(&naptime, NULL);
}
The first inner loop only sleeps when it has been over three seconds since the last SIGINT (or we never received one). It will be interrupted by both SIGINT and SIGALRM, so the duration does not matter.
The if (done) break; case just avoids printing anything if the user had lightning hands and typed Ctrl+C twice really fast.
The second inner loop only sleep when we are waiting for a second Ctrl+C. It too will be interrupted by both signals, so the duration here does not matter either. Note, however, that we do wish to check interrupted first, to ensure we catch all changes reliably. (If we checked done first, we might be interrupted before we check interrupted, and it is possible, in theory, that done changes to nonzero and interrupt to zero and then to 1 in the mean time. But, if we check interrupted first, and it is 1, any additional interrupts will just set done, which we'll catch. So, interrupted == 1 && done == 0 is the correct check in the correct order here.)
As noted above, the duration specified for nanosleep() does not actually matter, as it will be interrupted by the signal delivery anyway. Something like ten seconds should be fine,
struct timespec naptime = { .tv_sec = 10, .tv_nsec = 0L };
If the lecturer had recommended POSIX.1 functions (sigaction(), nanosleep()), this would have been surprisingly interesting exercise.
I have a question about handling a signal.
Assume that if we recieve SIGINT signal, we should print "Recieved Signal". If within ten seconds the handler recieves another signal, it should print "Shutting Down" then exit with status 1.
I made my code like this:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handler(int);
void secondhandler(int);
void alrmhandler(int);
void alrmhandler (int alrmsig)
{
alarm(0);
}
void secondhandler(int sig)
{
/* after recieving second signal prints shutting down and exit */
printf("Shutting Down\n");
exit(1);
}
void handler ( int sig )
{
/* recieve first SIGINT signal */
printf ("Recieved Signal\n");
/* handle for the alarm function */
signal(SIGALRM, alrmhandler);
/* start 10s alarm */
alarm(10);
/* catch second SIGINT signal within 10s*/
signal(SIGINT, secondhandler);
}
int main( void )
{
signal(SIGINT, handler);
printf( "Hello World!\n" );
for ( ;; )
{
/* infinite loop */
}
return 0;
}
I tried to compile it with dev c++, but it failed. Because SIGALRM undeclared(first use in this function).
Anyway, what I want to know is if this code is right. I actually kinda not sure with the alrmhandler(). should I ignore the SIGALRM?
If you are on a Windows platform, the only signals you will be able to send are : SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, or SIGTERM.
You write:
what I want to know is if this code is right.
Not entirely. printf() is not async-signal-safe, and so should not be called from within a signal handler unless you are very sure it is safe to do so. It is not safe to do so within the code you provide.
The alarm() technique is, generally, race-prone. Your ten second alarm might expire in the middle of your secondhandler() function. To guard against this, you might mask out signals to compensate with a more sophisticated signal manipulation function.
There are more elegant/flexible ways of implementing the timeout you desire, but that's perhaps a question better suited for codereview.stackexchange.com.
The example code of section 10.6, the expected result is:
after several iterations, the static structure used by getpwnam will be corrupted, and the program will terminate with SIGSEGV signal.
But on my platform, Fedora 11, gcc (GCC) 4.4.0, the result is
[Langzi#Freedom apue]$ ./corrupt
in sig_alarm
I can see the output from sig_alarm only once, and the program seems hung up for some reason, but it does exist, and still running.
But when I try to use gdb to run the program, it seems OK, I will see the output from sig_alarm at regular intervals.
And from my manual, it said the signal handler will be set to SIG_DEF after the signal is handled, and system will not block the signal. So at the beginning of my signal handler I reset the signal handler.
Maybe I should use sigaction instead, but I only want to know the reason about the difference between normal running and gdb running.
Any advice and help will be appreciated.
following is my code:
#include "apue.h"
#include <pwd.h>
void sig_alarm(int signo);
int main()
{
struct passwd *pwdptr;
signal(SIGALRM, sig_alarm);
alarm(1);
for(;;) {
if ((pwdptr = getpwnam("Zhijin")) == NULL)
err_sys("getpwnam error");
if (strcmp("Zhijin", pwdptr->pw_name) != 0) {
printf("data corrupted, pw_name: %s\n", pwdptr->pw_name);
}
}
}
void sig_alarm(int signo)
{
signal(SIGALRM, sig_alarm);
struct passwd *rootptr;
printf("in sig_alarm\n");
if ((rootptr = getpwnam("root")) == NULL)
err_sys("getpwnam error");
alarm(1);
}
According to the standard, you're really not allowed to do much in a signal handler. All you are guaranteed to be able to do in the signal-handling function, without causing undefined behavior, is to call signal, and to assign a value to a volatile static object of the type sig_atomic_t.
The first few times I ran this program, on Ubuntu Linux, it looked like your call to alarm in the signal handler didn't work, so the loop in main just kept running after the first alarm. When I tried it later, the program ran the signal handler a few times, and then hung. All this is consistent with undefined behavior: the program fails, sometimes, and in various more or less interesting ways.
It is not uncommon for programs that have undefined behavior to work differently in the debugger. The debugger is a different environment, and your program and data could for example be laid out in memory in a different way, so errors can manifest themselves in a different way, or not at all.
I got the program to work by adding a variable:
volatile sig_atomic_t got_interrupt = 0;
And then I changed your signal handler to this very simple one:
void sig_alarm(int signo) {
got_interrupt = 1;
}
And then I inserted the actual work into the infinite loop in main:
if (got_interrupt) {
got_interrupt = 0;
signal(SIGALRM, sig_alarm);
struct passwd *rootptr;
printf("in sig_alarm\n");
if ((rootptr = getpwnam("root")) == NULL)
perror("getpwnam error");
alarm(1);
}
I think the "apue" you mention is the book "Advanced Programming in the UNIX Environment", which I don't have here, so I don't know if the purpose of this example is to show that you shouldn't mess around with things inside of a signal handler, or just that signals can cause problems by interrupting the normal work of the program.
According to the spec, the function getpwnam is not reentrant and is not guaranteed to be thread safe. Since you are accessing the structure in two different threads of control (signal handlers are effectively running in a different thread context), you are running into this issue. Whenever you have concurrent or parallel execution (as when using pthreads or when using a signal handler), you must be sure not to modify shared state (e.g. the structure owned by 'getpwnam'), and if you do, then appropriate locking/synchronization must be used.
Additionally, the signal function has been deprecated in favor of the sigaction function. In order to ensure portable behavior when registering signal handlers, you should always use the sigaction invocation.
Using the sigaction function, you can use the SA_RESETHAND flag to reset the default handler. You can also use the sigprocmask function to enable/disable the delivery of signals without modifying their handlers.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void sigalrm_handler(int);
int main()
{
signal(SIGALRM, sigalrm_handler);
alarm(3);
while(1)
{
}
return 0;
}
void sigalrm_handler(int sign)
{
printf("I am alive. Catch the sigalrm %d!\n",sign);
alarm(3);
}
For example, my code is runing in main doing nothing and every 3 seconds my program says im alive x)
I think that if you do as i done calling in the handler function alarm with value 3, the problem is resolved :)
I'm building some FastCGI apps and it sort of bugs me that lighttpd doesn't kill them off after they've been idle, so I'm trying to have them close on their own.
I tried using
signal(SIGALRM, close);
alarm(300);
and having the close function execute exit(0), and that works almost well.
The problem is the close function is being called every time the main program loop runs though (I call alarm(300) each loop to reset it). I've read the man page for alarm() and it doesn't seem as though calling it multiple times with the same value should trip SIGALRM so I'm assuming Lighttpd is sending an alarm signal.
The big question! Is there a way to run a method after a specific interval, and have that interval be resettable without SIGALRM? I'd be nice if I could have multiple alarms as well.
Here's the whole app thus far:
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include "fcgiapp.h"
FCGX_Stream *in, *out, *err;
FCGX_ParamArray envp;
int calls = 0;
void print(char*, ...);
void close();
int main(void)
{
// If I'm not used for five minutes, leave
signal(SIGALRM, close);
int reqCount = 0;
while (FCGX_Accept(&in, &out, &err, &envp) >= 0)
{
print("Content-type: text/plain\r\n\r\n");
int i = 0;
char **elements = envp;
print("Environment:\n");
while (elements[i])
print("\t%s\n", elements[i++]);
print("\n\nDone. Have served %d requests", ++reqCount);
print("\nFor some reason, close was called %d times", calls);
alarm(300);
}
return 0;
}
void print(char *strFormat, ...)
{
va_list args;
va_start(args, strFormat);
FCGX_VFPrintF(out, strFormat, args);
va_end(args);
}
void close()
{
calls++;
// exit(0);
}
the best way is: add a thread so that you can remove signal and alarm, and sync the thread and your main code (main thread).
I'd probably use POSIX timers. Timers do not have to use signals. You have a choice between not notifying at all, raising a signal, or running a function as a new thread (which I would do as it will not interfere with fastcgi).
Make sure you include <signal.h> and <time.h>, and link with -lrt
First, I'd fill out your sigevent structure:
struct sigevent myTimerSignal = {
.sigev_notify = SIGEV_THREAD,
.sigev_notify_function = close //Make sure you change your function declaration to close(union sigval), you do not need to use the sigval unless you store data in your event too
};
Now create your timer:
timer_t myTimer;
if(timer_create(CLOCK_REALTIME, &myTimerSignal, &myTimer)){
//An error occurred, handle it
}
Lets arm it, it will call close() in a new thread in 300 seconds:
struct itimerspec timeUntilClose = {
.it_value = {
.tv_sec = 300 //300 seconds
}
};
if(timer_settime(myTimer, 0, &timeUntilClose, NULL)){
//Handle the error
}
Now, you should have a timer ready to stop the program after 300 seconds. I know I may be late, but I hope this helps a future reader.
Maybe you can wrap the close function by another function which will first call sleep()?
The argument to the alarm call is seconds, not minutes. So you're asking to be woken up in 5 seconds after each time through the main loop.
Here's a solution that sort of avoids the point of the question, but it works. It will respond to only my application's signal events:
void close(int intSignal, siginfo_t *info, void *context)
{
// For some stupid reason MY signal doesn't populate siginfo_t
if (!info)
{
count++;
}
}
If the siginfo struct is empty, that's because alarm() tripped it. If an outside process does it, siginfo_t.si_pid is populated with zero.
I still don't like this solution, but it works. Odd problem now is that doing an exit(0) doesn't close the application, though lighttpd thinks it's gone and spawns another. This means that now I've got rouge processes. raise(SIGUSR1) which is what is supposed to stop FastCGI scripts doesn't seem to do the trick either... hmmm...
Question still remains: How does one call asynchronous functions on an interval timer without the use of signals?
Try to close all the file descriptors (including stdin and stdout). This should close the CGI instance if its idle.
You can use select() with timeout to schedule instead of SIGALRM