RAD Studio
ContentsIndex
PreviousUpNext
signal (C RTL)

Header File 

signal.h  

Category 

Process Control Routines 

Prototype 

void (_USERENTRY *signal(int sig, void (_USERENTRY *func)(int sig[, int subcode])))(int); 

Description 

Specifies signal-handling actions. 

signal determines how receipt of signal number sig will subsequently be treated. You can install a user-specified handler routine (specified by the argument func) or use one of the two predefined handlers, SIG_DFL and SIG_IGN, in signal.h. The function func must be declared with the _USERENTRY calling convention. 

A routine that catches a signal (such as a floating point) also clears the signal. To continue to receive signals, a signal handler must be reinstalled by calling signal again.

SIG_DFL 
Terminates the program 
SIG_ERR 
Indicates an error return from signal 
SIG_IGN 
Ignore this type signal 

The following table shows signal types and their defaults:

SIGBREAK 
Keyboard must be in raw mode. 
SIGABRT  
Abnormal termination. Default action is equivalent to calling _exit(3). 
SIGFPE 
Arithmetic error caused by division by 0, invalid operation, and the like. Default action is equivalent to calling _exit(1). 
SIGILL 
Illegal operation. Default action is equivalent to calling _exit(1). 
SIGINT 
Ctrl-C interrupt. Default action is equivalent to calling _exit(3). 
SIGSEGV 
Illegal storage access. Default action is equivalent to calling _exit(1). 
SIGTERM 
Request for program termination. Default action is equivalent to calling _exit(1). 
 
 
 
User-defined signals can be generated only by calling raise. Default action is to ignore the signal. 

signal.h defines a type called sig_atomic_t, the largest integer type the processor can load or store atomically in the presence of asynchronous interrupts (this is a 32-bit integer -- a Borland C++ integer). 

When a signal is generated by the raise function or by an external event, the following two things happen:

  • If a user-specified handler has been installed for the signal, the action for that signal type is set to SIG_DFL.
  • The user-specified function is called with the signal type as the parameter.
User-specified handler functions can terminate by a return or by a call to abort, _exit, exit, or longjmp. If your handler function is expected to continue to receive and handle more signals, you must have the handler function call signal again. 

Borland C++ implements an extension to ANSI C when the signal type is SIGFPE, SIGSEGV, or SIGILL. The user-specified handler function is called with one or two extra parameters. If SIGFPE, SIGSEGV, or SIGILL has been raised as the result of an explicit call to the raise function, the user-specified handler is called with one extra parameter, an integer specifying that the handler is being explicitly invoked. The explicit activation values for SIGFPE, SIGSEGV and SIGILL are as follows

Note: Declarations of these types are defined in float.h.

SIGFPE 
FPE_EXPLICITGEN 
SIGSEGV 
SEGV_EXPLICITGEN 
SIGILL 
ILL_EXPLICITGEN 

If SIGFPE is raised because of a floating-point exception, the user handler is called with one extra parameter that specifies the FPE_xxx type of the signal. If SIGSEGV, SIGILL, or the integer-related variants of SIGFPE signals (FPE_INTOVFLOW or FPE_INTDIV0) are raised as the result of a processor exception, the user handler is called with two extra parameters: 

1.The SIGFPE, SIGSEGV, or SIGILL exception type (see float.h for all these types). This first parameter is the usual ANSI signal type. 

2.An integer pointer into the stack of the interrupt handler that called the user-specified handler. This pointer points to a list of the processor registers saved when the exception occurred. The registers are in the same order as the parameters to an interrupt function; that is, EBP, EDI, ESI, EDS, ES, EDX, ECX, EBX, EAX, EIP, CS, EFL. To have a register value changed when the handler returns, change one of the locations in this list.  

For example, to have a new SI value on return, do something like this: 

*((int*)list_pointer + 2) = new_SI_value; 

In this way, the handler can examine and make any adjustments to the registers that you want.  

The following SIGFPE-type signals can occur (or be generated). They correspond to the exceptions that the 80x87 family is capable of detecting, as well as the "INTEGER DIVIDE BY ZERO" and the "INTERRUPT ON OVERFLOW" on the main CPU. (The declarations for these are in float.h.)

FPE_INTOVFLOW 
INTO executed with OF flag set 
FPE_INTDIV0 
Integer divide by zero 
FPE_INVALID 
Invalid operation 
FPE_ZERODIVIDE 
Division by zero 
FPE_OVERFLOW 
Numeric overflow 
FPE_UNDERFLOW  
Numeric underflow 
FPE_INEXACT  
Precision 
FPE_EXPLICITGEN 
User program executed raise(SIGFPE) 
FPE_STACKFAULT 
Floating-point stack overflow or underflow 
FPE_STACKFAULT 
Stack overflow 

The FPE_INTOVFLOW and FPE_INTDIV0 signals are generated by integer operations, and the others are generated by floating-point operations. Whether the floating-point exceptions are generated depends on the coprocessor control word, which can be modified with _control87. Denormal exceptions are handled by Borland C++ and not passed to a signal handler. 

The following SIGSEGV-type signals can occur:

SEGV_BOUND 
Bound constraint exception 
SEGV_EXPLICITGEN 
raise(SIGSEGV) was executed 

The following SIGILL-type signals can occur:

ILL_EXECUTION 
Illegal operation attempted 
ILL_EXPLICITGEN 
raise(SIGILL) was executed 

When the signal type is SIGFPE, SIGSEGV, or SIGILL, a return from a signal handler is generally not advisable if the state of the floating point processor is corrupt, the results of an integer division are wrong, an operation that shouldn't have overflowed did, a bound instruction failed, or an illegal operation was attempted. The only time a return is reasonable is when the handler alters the registers so that a reasonable return context exists or the signal type indicates that the signal was generated explicitly (for example, FPE_EXPLICITGEN, SEGV_EXPLICITGEN, or ILL_EXPLICITGEN). Generally in this case you would print an error message and terminate the program using _exit, exit, or abort. If a return is executed under any other conditions, the program's action will probably be unpredictable.

Note: Take special care when using the signal function in a multithread program. The SIGINT, SIGTERM, and SIGBREAK signals can be used only by the main thread (thread one) in a non-Win32 application. When one of these signals occurs, the currently executing thread is suspended, and control transfers to the signal handler (if any) set up by thread one. Other signals can be handled by any thread.
Note: A signal handler should not use C++ runtime library functions, because a semaphore deadlock might occur. Instead, the handler should simply set a flag or post a semaphore, and return immediately.
Return Value 

On success, signal returns a pointer to the previous handler routine for the specified signal type.  

On error, signal returns SIG_ERR, and the external variable errno is set to EINVAL. 

Example  

/* signal example */
/* 
    This example installs a signal handler routine for SIGFPE, 
    catches an integer overflow condition, makes an adjustment to AX 
    register, and returns.  This example program MAY cause your computer 
    to crash, and will produce runtime errors depending on which memory 
    model is used.
*/
#pragma inline
#include <stdio.h>
#include <signal.h>
#ifdef __cplusplus
   typedef void (*fptr)(int);
#else
   typedef void (*fptr)();
#endif
void Catcher(int *reglist)
{
   signal(SIGFPE, (fptr)Catcher);  //  ******reinstall signal handler
   printf("Caught it!\n"); *(reglist + 8) = 3; /* make return AX = 3 */
}
int main(void)
{
   signal(SIGFPE, (fptr)Catcher);  /* cast Catcher to appropriate type */
   asm     mov     ax,07FFFH       /* AX = 32767 */
   asm     inc     ax              /* cause overflow */
   asm     into                    /* activate handler */
   /* The handler set AX to 3 on return. If that had not happened,
      there would have been another exception when the next 'into'
      executed after the 'dec' instruction. */
   asm     dec     ax              /* no overflow now */
   asm     into                    /* doesn't activate */
   return 0;
}

Portability

POSIX 
Win32 
ANSI C 
ANSI C++ 
Copyright(C) 2008 CodeGear(TM). All Rights Reserved.
What do you think about this topic? Send feedback!