qc.hlp (Table of Contents; Topic list)
Important Notice
The pages on this site contain documentation for very old MS-DOS software, purely for historical purposes. If you're looking for up-to-date documentation, particularly for programming, you should not rely on the information found here, as it will be woefully out of date.
SIGNAL.C
                                             Up Contents Index Back
────────────────────────────────────────────────────────────────────────────
 
/* SIGNAL.C illustrates setting up signal interrupt routines. Functions
 * illustrated include:
 *      signal          abort           raise
 *
 * Since C I/O functions are not safe inside signal routines, the code
 * uses conditionals to use system-level DOS services. Another
 * option is to set global flags and do any I/O operations outside the
 * signal handler. This technique is illustrated in SIGFP.C.
 */
 
#include <stdio.h>
#include <conio.h>
#include <signal.h>
#include <process.h>
#include <setjmp.h>
#include <stdlib.h>
#include <float.h>
#include <dos.h>
#include <bios.h>
 
void ctrlchandler( void );          /* Prototypes */
void safeout( char *str );
int safein( void );
 
void main()
{
    int ch;
 
    /* Modify CTRL+C behavior. */
    if( signal( SIGINT, ctrlchandler ) == SIG_ERR )
    {
        fprintf( stderr, "Couldn't set SIGINT\n" );
        abort();
    }
 
    /* Input loop illustrates results. */
    do
    {
        ch = getch();
        if( ch == 0 )
        {
            ch = getch();
            if( ch == 46 )      /* Treat ALT+C like CTRL+C */
                raise( SIGINT );
            else
                printf( "Extended code: %X\n", ch );
        }
        else
            printf( "ASCII code: %X\n", ch );
    } while( ch != 27 );        /* ESC code */
}
 
/* Handles SIGINT (CTRL+C) interrupt. */
void ctrlchandler()
{
    int ch;
 
    /* Disallow CTRL+C during handler. */
    signal( SIGINT, SIG_IGN );
 
    safeout( "Abort processing? " );
    ch = safein();
    safeout( "\r\n" );
    if( (ch == 'y') || (ch == 'Y') )
        abort();
    else
 
        /* The CTRL+C interrupt must be reset to our handler since by
         * default it is reset to the system handler.
         */
        signal( SIGINT, ctrlchandler );
}
 
/* Outputs a string using system level calls. */
void safeout( char *str )
{
    union REGS inregs, outregs;
 
    inregs.h.ah = 0x0e;
    while( *str )
    {
        inregs.h.al = *str++;
        int86( 0x10, &inregs, &outregs );
    }
}
 
/* Inputs a character using system level calls. */
int safein()
{
    return (_bios_keybrd( _KEYBRD_READ ) & 0xff );
}