Borland C++ reference

signal

raw OCR

Specifies signal-handling actions.

Defined in header <signal.h>

Syntax

#include <signal.h>
void  (*signal(int sig, void C*func) (int sig[, int subcode]))){int);

Portability

DOSUNIXWindowsANSI CC++ only
■■■

Remarks

signal determines how receipt of signal number sig will subsequently be treated. You can install a user-specified handler routine or use one of the two predefined handlers, SIG_DFL and SIG_1GN, in signal.h.

Function pointerl\/leaning
SIG_DFLTerminates the program
SIG_IGNIgnore this type signal
SIG ERRIndicates an error return from signal

The signal types and their defaults are as follows:

Signal type Meaning

SIGABRTAbnormal termination. Default action is equivalent to calling _exit(3).
SIGFPEArithmetic error caused by division by 0, invalid operation, and the like. Default action is equivalent to calling _exit(l).
SIGILLIllegal operation. Default action is equivalent to calling _exit(l).
SIGINTCTRL-C interrupt. Default action is to do an INT 23h.
SIGSEGVIllegal storage access. Default action is equivalent to calling _exit(l).
SIGTERMRequest for program termination. Default action is equivalent to calling _exit(l).

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 (for the 8086 family, this is a 16-bit w^ord; that is, a Borland C++ integer).

When a signal is generated by the raise function or by an external event, the follow^ing happens:

1. If a user-specified handler has been installed for the signal, the action for that signal type is set to SIG_DFL. 2. The user-specified function is called vv^ith 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.

Borland C++ implements an extension to ANSI C when the signal type is SIGFPE, SIGSEGV, or SIGILL. The user-specified handler function is called w^ith 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 (see declarations in float.h):

SIGSEGV signalMeaning
SIGFPEFPE_EXPLICITGEN
SIGSEGVSEGV_EXPLICITGEN
SIGILL If SIGFPE is raised because of a floating-point exception, the user handler is called with one extra parameter that specifies the FPExxx type of the signal. If SIGSEGV, SIGILL, or the integer-related variants of SIGFPEILL EXPLICITGEN
signals (FPEJNTOVFLOW processor exception, the user handler is called with two extra parameters:or FPEJNTDIVO)are raised as the result of a

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, BP, DI, SI, DS, ES, DX, CX, BX, AX, IP, CS, FLAGS. 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. (See Example 2 for a demonstration.)

The following SIGFPE-type signals can occur (or be generated). They correspond to the exceptions that the 8087 family is capable of detecting,

as well as the "INTEGERDIVIDE BY ZERO" and the 'TNTERRUPTON
OVERFLOW"on the main CPU. (The declarations for these are in float.h.)
SIGFPE signalMeaning
FPEJNTOVFLOWINTO executed with OF flag set
FPE_INTDIVOInteger divide by zero
FPEJNVALIDInvalid operation
FPE_ZERODIVIDEDivision by zero
FPE_OVERFLOWNumeric overflow
FPE_UNDERFLOWNumeric underflow
FPEJNEXACTPrecision
FPE_EXPLICITGENUser program executed raise(SIGFPE)

\^

The FPEJNTOVFLOWand FPEJNTDIVOsignals 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-f-+ and not passed to a signal handler.

The following SIGSEGV-type signals can occur:

SEGV_BOUNDBound constraint exception
SEGV EXPLICITGENraise(SIGSEGV) was executed

The 8088 and 8086 processors don't have a bound instruction. The 186, 286, 386, and NEC V series processors do have this instruction. So, on the 8088

and 8086 processors, the SEGV_BOUNDtype of SIGSEGV signal won't

occur. Borland C++ doesn't generate bound instructions, but they can be used in inline code and separately compiled assembler routines that are linked in.

The following SIGILL-type signals can occur:

ILL_EXECUTIONIllegal operation attempted.
ILL EXPLICITGENraise(SIGILL) was executed.

The 8088, 8086, NEC V20, and NEC V30 processors don't have an illegal operation exception. The 186, 286, 386, NEC V40, and NEC V50 processors do have this exception type. So, on 8088, 8086, NEC V20, and NEC V30

processors, the ILL_EXECUTIONtype of SIGILL won't occur.

When the signal type is SIGFPE, SIGSEGV, or SIGILL, a return from a signal handler is generally not advisable because the state of the 8087 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 upon resuming.

Return value

If the call succeeds, signal returns a pointer to the previous handler routine for the specified signal type. If the call fails, signal returns SIG_ERR, and the external variable errno is set to EINVAL.

See also

Example

/* This example installs a signal handler routine to be  run when Ctrl-Break is
   pressed. */
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void catcher(void)
{
   printf("\nNow in break routine\n" );
   exit(l);
}
int main (void) {
   signaKSIGINT, catcher) ;
   for  (;;)
      printf ("\nln main() program\n";

/* 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 miemory model is used. */
ttpragma inline
#include <stdio.h>
finclude <signal.h>

void Catcher(int *reglist)
{
   printf("Caught it!\n");
   Mreglist  + 8) = 3;              /* make return AX = 3 */

int main (void)
{
   signal(SIGFPE, Catcher);
   asm     mov     ax,07FFFH        /* AX = 32757 */
   asm     inc     ax              /* cause overflow  */
   asm     into                    /* activate handler  */

   /* The handler set AX to 3 on return. If that hadn't  happened, there would
      have been another exception v/hen the next 'into' v/as executed after the
      'dec' instruction. */
   asm     dec     ax              /* no overflow now  */
   asm     into                    /* doesn't activate  */
   return 0;

Differences from modern implementations

Nothing recorded yet.

Modern references

These are search links, not yet checked by hand.