I was trying this program from Advance Programming in Unix Environment.
#include<stdio.h>
#include<signal.h>
static void handler(int sig){
if(sig == SIGUSR1)
printf("handled user1 signal");
else if(sig == SIGUSR2)
printf("handles user2 signal");
else
printf("unkown signal");
}
int main(){
if(signal(SIGUSR1, handler) == SIG_ERR)
printf("can't handle signal SIGUSR1");
if(signal(SIGUSR2, handler) == SIG_ERR)
printf("can't handle signal SIGUSR2");
for(;;)
pause();
return 0;
}
I am using Ubuntu 11.10. I compile the program with gcc and then run a.out as indicated in the book.
$./a.out& [1]+ 1345
$ kill -USR1 1345
But there is no output printed. The program keeps running in backgound and I have to kill it.
Other things I have tried:
Tried handling SIGINT to see if running program in background is causing problems. Still no output.
Downloaded latest release of FreeBSD and tried the same program on it, but with same problem.
I put a printf statement before setting signal handler:
int main(){
printf("printf is working...");
//exit(0);
if(signal(SIGUSR1, handler) == SIG_ERR)
...
when exit() is commented, there is no output. When I uncomment it, the output is printed.
Please tell me what am I doing wrong in this?
PS: Don't suggest using sigaction(). I am learning Unix Programming, not building any practical application.
You can use printf in signal handlers if you are using the pthread library.
printf is non-async-signal-safe because, as you describe, it ends up manipulating global state without synchronisation. For added fun, it's not necessarily re-entrant. In your example, the signal might be handled while the first printf is running, and the second printf could mess up the state of the first call.
The signal() system call just installs the handler: "signal() sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer-defined function (a "signal handler")." There you go.
The behavior of signal() has been changed multiple times across history and is now considered deprecated.
The output from printf
is buffered. That means it's stored in memory until flushed to the output. The best way to flush text in printf
is to end the text with a newline. You can also flush manually with the fflush
function.
However, you should be cautioned that using output functions like printf
and fflush
is not considered safe in signal handlers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With