signal()

Updated: October 28, 2024

Set handling for exceptional conditions

Synopsis:

#include <signal.h>

void ( * signal( int sig, 
                void ( * func)(int) ) )( int );

Arguments:

sig
The signal number (defined in <signal.h>). For more information, see POSIX and QNX Neutrino signals in the documentation for SignalAction().

If the signal terminates a process, the cleanup of the terminated process occurs by default at the priority of the thread that sent the signal. As a QNX Neutrino extension, if you OR the SIG_TERMER_NOINHERIT flag (defined in <signal.h>) into sig, the cleanup occurs at the priority of the thread that received the signal.

func
SIG_DFL, SIG_IGN, or a pointer to the function that you want to call when the signal is raised.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The signal() function is used to specify an action to take place when certain conditions are detected while a program executes. See the <signal.h> header file for definitions of these conditions, and also refer to the System Architecture manual.

Note: The sigaction() function provides a more comprehensive and reliable mechanism for controlling signals; new applications should use it instead of signal().

There are three types of actions that can be associated with a signal: SIG_DFL, SIG_IGN or a pointer to a function. Initially, all signals are set to SIG_DFL or SIG_IGN prior to entry of the main() routine. An action can be specified for each of the conditions, depending upon the value of the func argument, as discussed below.

func is a function

If func points to a function, its prototype must be:

void func( int sig_no )
{
  …
}

The func function may do the following:

Note: (QNX Neutrino 7.1 or later) The kernel saves and restores the FPU context on entering and leaving signal handlers, so it's safe to use floating-point operations in them.

After returning from the signal-catching function, the receiving process resumes execution at the point at which it was interrupted.

It isn't possible to catch the SIGSTOP or SIGKILL signals.

Since signal-catching functions are invoked asynchronously with process execution, you need to take into account the same sort of things that you would in a multithreaded program when inspecting or manipulating shared resources. Signal handlers aren't nested, and a handler can't be called a second time while a current instance is still being executed.

func is SIG_DFL

If func is SIG_DFL, the default action for the condition is taken.

If the default action is to stop the process, the execution of that process is temporarily suspended. When a process stops, a SIGCHLD signal is generated for its parent process, unless the parent process has set the SA_NOCLDSTOP flag (see sigaction()). While a process is stopped, any additional signals that are sent to the process aren't delivered until the process is continued, except SIGKILL, which always terminates the receiving process.

Setting a signal action to SIG_DFL for a signal that is pending, and whose default action is to ignore the signal (for example, SIGCHLD), causes the pending signal to be discarded, whether or not it's blocked.

func is SIG_IGN

If func is SIG_IGN, the indicated condition is ignored.

You can't set the action for the SIGSTOP and SIGKILL signals to SIG_IGN.

Setting a signal action to SIG_IGN for a signal that's pending causes the pending signal to be discarded, whether or not it is blocked.

If a process sets the action for the SIGCHLD signal to SIG_IGN, its children won't enter the zombie state and the process can't use wait() or waitpid() to wait on their deaths.

Handling a condition

When a condition is detected, it may be handled by a program, it may be ignored, or it may be handled by the usual default action (often causing an error message to be printed on the stderr stream followed by program termination).

A condition can be generated by a program using the raise() or kill() function

Returns:

The previous value of func for the indicated condition, or SIG_ERR if the request couldn't be handled (errno is set to EINVAL).

Examples:

#include <stdlib.h>
#include <signal.h>

sig_atomic_t signal_count;

void MyHandler( int sig_number )
  {
     ++signal_count;
  }

int main( void )
  {
    signal( SIGFPE, MyHandler );   /* set own handler */
    signal( SIGABRT, SIG_DFL );    /* Default action */
    signal( SIGFPE, SIG_IGN );     /* Ignore condition */
    return (EXIT_SUCCESS);
  }

Classification:

ANSI, POSIX 1003.1

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes
  翻译: