Can I find out why the first line of output is before the first kill ()? Why did the trap () not get control first?
You have installed a signal handler that catches SIGUSR1 . Until SIGUSR1 is delivered to the process, normal program execution flow will continue. So here:
printf("before first kill()\n"); kill(getpid(), SIGUSR1);
You only generate a signal after printing before first kill() . Why don't you expect this to appear before catcher() has gained control ? In other words, when you call printf("before first kill()\n"); , the signals have not yet been raised, so you can expect that the execution of the program will remain normal.
This line:
kill(getpid(), SIGUSR1);
Creates SIGUSR1 . The operating system transmits a signal to the process at a convenient time. Since you installed a handler for SIGUSR1 , your signal handler ( catcher() ) is called. You pick up the signal after printing the first line, so it is expected that the next line of output will come from the signal handler.
Note that printf(3) not safe for an asynchronous signal, so technically you cannot call it from within the signal handler, but this is usually normal for these toy examples.
From what I know, sa_handler consists of two types of signals, default signals and ignoring the signal.
There is more than that. The sa_handler struct sigaction can have SIG_DFL values, which corresponds to the action of the default signal (the default action is specified in man signal ) and SIG_IGN , which means that the signal is ignored (nothing happens when it is raised). But sa_handler can also be a pointer to a function that you want to call every time a signal is sent. This is what the code you showed does - it says: "Hey, when SIGUSR1 delivered, call catcher() .
How do we know which signal it will generate? Why would this cause the print trap function () to gain control if the signal is ignored by the generation?
You indicated the signal ( SIGUSR1 ) when you called sigaction(2) to configure the handler. Thus, catcher() will be called upon delivery of SIGUSR1 .
Also, what is the sa_mask function in this program? In my understanding, sa_mask will block the specified signal.
This is a signal mask that is atomically set when the signal handler is entered and is deleted when the signal handler returns. By default, even if you pass it an empty mask, the captured signal is always blocked when the handler is entered (if the SA_NODEFER flag SA_NODEFER not set in the struct sigaction )). However, you can block other signals during the execution of the handler β the way you do this by specifying these signals in sa_mask .