tags:

views:

661

answers:

2

I had defined my own signal handler for SIGINT. But my signal handler doesn't get called The signal handler just terminates the program. But on pressing ctrl+c, the program doesn't quit. Please help...

This is how the code looks..

sa.sa_handler = handle_termsig;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
sigemptyset(&g_termsigs);
sigaddset(&g_termsigs, SIGINT);
sigaddset(&g_termsigs, SIGTERM);

sigprocmask(SIG_BLOCK, &g_termsigs, 0);
if (select (fdmax+1, &rd, &wr, NULL, &time) < 0)
{
  exit();
}
sigprocmask(SIG_UNBLOCK, &g_termsigs, &savemask);
A: 

Since the SIGINT is blocked while you call select, it is not delivered and select() is not interrupted. If your handler just calls exit() and you want this even while your code calls select, the best solution would be to leave the signal mask alone. If you, for some reason, don't want your normal handler to be called while you call select(), you can use the pselect() function.

Edit:

When is the signal delivered

If the signal is enabled (ie. not blocked) and the process is running, immediately.

If the signal is enabled and the process is sleeping in an interruptible sleep (that means state==S in top/ps output), the syscall is interrupted (eg. by returning EINTR to the caller) and the signal handler is executed.

If the signal is blocked, it waits is delivered as soon as it is unblocked. Syscalls are not interrupted by blocked signals.

In your example, this means the select() is waiting for input; when input becomes available, it returns, signal handler gets enabled (in the second call to sigprocmask) and handler is called.

This is how it looks in strace:

Process 22393 attached - interrupt to quit
19:31:05.844940 select(1, [0], NULL, NULL, NULL) = 1 (in [0])
19:31:12.131431 rt_sigprocmask(SIG_UNBLOCK, [INT TERM], [INT TERM], 8) = 0
19:31:12.131560 --- SIGINT (Interrupt) @ 0 (0) ---
19:31:12.131730 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
19:31:12.131871 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ffb000
19:31:12.132027 write(1, "signal..."..., 9) = 9
19:31:12.132148 exit_group(1)           = ?
Process 22393 detached

How to enable the signals

To have the signal handler enabled all the time, just remove the calls to sigprocmask() from your code.

jpalecek
Doesnt the signal get delivered once we exit out of select()?
I want the first option - My handler should be called even when i call select. How should the code be modified??
just get rid of all of the sigprocmask code altogether
Alnitak
A: 

You're explicitly blocking SIGINT around the select call, so of course it doesn't work.

What are you trying to do?

Alnitak
My guess was that the signal would be delivered after un blocking it. Is that correct?
yes, but if your select call has an infinite timeout it won't return until one of your FDs is ready.
Alnitak