Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why no output on console on signal handling?

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:

  1. Tried handling SIGINT to see if running program in background is causing problems. Still no output.

  2. Downloaded latest release of FreeBSD and tried the same program on it, but with same problem.

  3. 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.

like image 793
Shashank Jain Avatar asked Aug 27 '12 09:08

Shashank Jain


People also ask

Can you use printf in signal handler?

You can use printf in signal handlers if you are using the pthread library.

Why is printf not a safe signal?

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.

Does signal () call the signal handler?

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.

Is signal deprecated?

The behavior of signal() has been changed multiple times across history and is now considered deprecated.


1 Answers

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.

like image 187
Some programmer dude Avatar answered Oct 22 '22 00:10

Some programmer dude