www.delorie.com/djgpp/doc/libc/libc_724.html   search  
libc.a reference

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]



#include <signal.h>

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


Signals are generated in response to some exceptional behavior of the program, such as division by 0. A signal can also report some asynchronous event outside the program, such as someone pressing a Ctrl-BREAK key combination.

Signals are numbered 0..255 for software interrupts and 256..287 for exceptions (exception number plus 256); other implementation-specific codes are specified in <signal.h> (see below). Every signal is given a mnemonic which you should use for portable programs.

By default, signal SIGQUIT is discarded. This is so programs ported from other DOS environments, where SIGQUIT is generally not supported, continue to work as they originally did. If you want SIGQUIT to abort with a traceback, install __djgpp_traceback_exit as its handler (see section __djgpp_traceback_exit).

The default handling for the rest of the signals is to print a traceback (a stack dump which describes the sequence of function calls leading to the generation of the signal) and abort the program by calling _exit (see section _exit). As an exception, the default handler for the signal SIGINT doesn't print the traceback, and calls exit instead of _exit, when the INTR key (Ctrl-C by default) is pressed, so that programs could be shut down safely in this manner. SIGINT raised by Ctrl-BREAK does generate the traceback.

The function signal allows you to change the default behavior for a specific signal. It registers func as a signal handler for signal number sig. After you register your function as the handler for a particular signal, it will be called when that signal occurs. The execution of the program will be suspended until the handler returns or calls longjmp (see section longjmp).

The state of the floating-point unit (FPU) is not saved, before entering a signal handler. It can be extremely costly to save the FPU state. Most signal handlers do not use floating-point operations, so the overhead of saving FPU state is avoided. An example of a signal handler that saves the FPU state is the function dbgsig in `src/debug/common/dbgcom.c' in the DJGPP sources.

You may pass SIG_DFL as the value of func to reset the signal handling for the signal sig to default (also See section __djgpp_exception_toggle, for a quick way to restore all the signals' handling to default), SIG_ERR to force an error when that signal happens, or SIG_IGN to ignore that signal. Signal handlers that you write are regular C functions, and may call any function that the ANSI/POSIX specs say are valid for signal handlers. For maximum portability, a handler for hardware interrupts and processor exceptions should only make calls to signal, assign values to data objects of type volatile sig_atomic_t (defined as int on <signal.h>) and return. Handlers for hardware interrupts need also be locked in memory (so that the operation of virtual memory mechanism won't swap them out), See section locking memory regions. Handlers for software interrupts can also terminate by calling abort, exit or longjmp.

The following signals are defined on <signal.h>:


The Abort signal. Currently only used by the assert macro to terminate the program when an assertion fails (see section assert), and by the abort function (see section abort).


The Floating Point Error signal. Generated in case of divide by zero exception (Int 00h), overflow exception (Int 04h), and any x87 co-processor exception, either generated by the CPU (Int 10h), or by the co-processor itself (Int 75h). The co-processor status word is printed by the default handler for this signal. See section _status87, for the definition of the individual bits of the status word.

The DJGPP startup code masks all numeric exceptions, so this signal is usually only triggered by an integer divide by zero operation. If you want to unmask some of the numeric exceptions, see _control87.


The Invalid Execution signal. Currently only generated for unknown/invalid exceptions.


The Interrupt signal. Generated when an INTR key (Ctrl-C by default) or Ctrl-BREAK (Int 1Bh) key is hit. Note that when you open the console in binary mode, or switch it to binary mode by a call to setmode (see section setmode), generation of SIGINT as result of Ctrl-C key is disabled. This is so for programs (such as Emacs) which want to be able to read the `^C' character as any other character. Use the library function __djgpp_set_ctrl_c to restore SIGINT generation when Ctrl-C is hit, if you need this. See section __djgpp_set_ctrl_c, for details on how this should be done. Ctrl-BREAK always generates SIGINT.

DJGPP hooks the keyboard hardware interrupt (Int 09h) to be able to generate SIGINT in response to the INTR key; you should be aware of this when you install a handler for the keyboard interrupt.

Note that the key which generates SIGINT can be changed with a call to __djgpp_set_sigint_key function. See section __djgpp_set_sigint_key.


The invalid storage access (Segmentation Violation) signal. Generated in response to any of the following exceptions: Bound range exceeded in BOUND instruction (Int 05h), Double Exception or an exception in the exception handler (Int 08h), Segment Boundary violation by co-processor (Int 09h), Invalid TSS (Int 0Ah), Segment Not Present (Int 0Bh), Stack Fault (Int 0Ch), General Protection Violation (Int 0Dh), or Page Fault (Int 0Eh). Note that Int 09h is only generated on 80386 processor; i486 and later CPUs cause Int 0Dh when the co-processor accesses memory out of bounds. The Double Exception, Invalid TSS, Segment Not Present, Stack Fault, GPF, and Page Fault exceptions will cause an error code to be printed, if it is non-zero.


The Termination Request signal. Currently unused.

The signals below this are not defined by ANSI C, and cannot be used when compiling under `-ansi' option to `gcc'.


The Alarm signal. Generated after certain time period has passed after a call to alarm library function (see section alarm).


The Hang-up signal. Currently unused.


The Kill signal. Currently unused.


The Broken Pipe signal. Currently unused.


The Quit signal. Generated when the QUIT key (Ctrl-\ by default) is hit. The key that raises the signal can be changed with a call to __djgpp_set_sigquit_key function. See section __djgpp_set_sigquit_key. By default, SIGQUIT is discarded, even if its handler is SIG_DFL, so that DOS programs which don't expect it do not break. You can change the effect of SIGQUIT to abort with traceback by installing __djgpp_traceback_exit as its handler. See section __djgpp_traceback_exit.

DJGPP hooks the keyboard hardware interrupt (Int 09h) to be able to generate SIGQUIT in response to the QUIT key; you should be aware of this when you install a handler for the keyboard interrupt.


User-defined signal no. 1.


User-defined signal no. 2.

The signals below are not defined by ANSI C and POSIX, and cannot be used when compiling under either `-ansi' or `-posix' options to `gcc'.


The Trap Instruction signal. Generated in response to the Debugger Exception (Int 01h) or Breakpoint Exception (Int 03h).


The No Co-processor signal. Generated if a co-processor (floating-point) instruction is encountered when no co-processor is installed (Int 07h).


The Timer signal. Used by the setitimer and alarm functions (See section setitimer, and see section alarm).


The Profiler signal. Used by the execution profile gathering code in a program compiled with `-pg' option to `gcc'.

Return Value

The previous handler for signal sig, or SIG_ERR if the value of sig is outside legal limits.

Signal Mechanism Implementation Notes

Due to subtle aspects of protected-mode programs operation under MS-DOS, signal handlers cannot be safely called from hardware interrupt handlers. Therefore, DJGPP exception-handling mechanism arranges for the signal handler to be called on the first occasion that the program is in protected mode and touches any of its data. This means that if the exception occurs while the processor is in real mode, like when your program calls some DOS service, the signal handler won't be called until that call returns. For instance, if you call read (or scanf, or gets) to read text from the console and press Ctrl-C, you will have to press Enter to terminate the read call to cause the signal handler for SIGINT to be called. Another significant implication of this implementation is that when the program isn't touching any of its data (like in very tight loops which only use values in the registers), it cannot be interrupted.


POSIX 1003.2-1992; 1003.1-2001

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2004   by DJ Delorie     Updated Apr 2004