[comp.sys.ibm.pc] How to inhibit ^C from appearing

bright@Data-IO.COM (Walter Bright) (04/13/89)

In article <1075@ptolemy.arc.nasa.gov> raymond@ptolemy.arc.nasa.gov (Eric A. Raymond) writes:
>Now, how to get rid of the ^C echo?

This requires:
1. Save the state of DOS break checking (DOS function 0x33).
2. Turn off DOS break checking (DOS function 0x33).
3. Intercept interrupt 0x23 (the ^C interrupt).
4. Intercept interrupt 0x1B (the cntl-break interrupt). This is not portable
   to non-IBM clone BIOSes. Intercepting this will prevent DOS from
   getting control when a cntl-break occurs. 0x1B is issued by the BIOS
   when a cntl-break is detected.
5. Don't call any of the DOS functions that always do break checking.

Now, if the user presses cntl-break, your handler gets it. If the user
presses ^C, it will either appear as an interrupt 0x23, or will appear in
the BIOS keyboard buffer (int 0x16), depending on if you got to it before
DOS did.

Upon program exit, be sure and:
1. Restore the previous 0x1B handler.
2. Restore the original state of the DOS break checking.
3. The previous 0x23 handler will be automatically restored by DOS.

I've used the above successfully to eliminate the ^C appearing all over my
screen oriented program.

Another technique that works in text mode is to intercept interrupt 0x23,
and have your service routine set a global flag. In the main loop, check
the flag. If it's set, simply rewrite the entire screen, then clear the
flag. I've used this technique too, when I wanted to be entirely
MS-DOS portable.

marks@tekigm2.MEN.TEK.COM (Mark D. Salzman) (04/17/89)

One method I have used with sucess is shown below in C for MSC v4 or higher:

/*
 * This function clears the input buffer and waits for the next character
 * to be typed. It ignores the BREAK (^C) signal and will not echo it to
 * the screen.
 */
#include <dos.h>

int getkey()
{
    union REGS rg;

    rg.h.ah = 0x0C;	/* Use DOS call to clear keyboard buffer, */
    rg.h.al = 0x07;	/* and get next keyboard input. */
    int86(0x21,&rg,&rg);
    return((int)(rg.h.al));	/* Return the key pressed */
}

Drawbacks to this function are that it clears the buffer so type ahead is
nullified, function keys are not handled (though I think this can be fixed),
and BREAK is not actually turned off, it is just ignored by this DOS call.
If any other DOS keyboard function in called (like the one that checks
for a key pressed), DOS will check for BREAK and echo ^C to the screen.

I used this once in a simple password program and it worked on several
machines.

Hope this is useful.

-- 
Mark D. Salzman    Phone: (206) 253-5542.  |  The more complex the mind,
Tektronix Inc., P.O. Box 3500, M/S C1-936  |  the greater the need for 
Vancouver, Washington. 98668               |  the simplicity of play.
E-MAIL: marks@tekigm2.MEN.TEK.COM          |       James T. Kirk