waynet@kit.tek.com (Wayne Turner) (04/11/91)
In article <mazz.671291088@jupiter.newcastle.edu.au> mazz@jupiter.newcastle.edu.au (Richard Mazzaferri) writes: >I'm developing an application which runs in EGA graphics mode, and also >requires that CTRL-BREAK be used by the user to interrupt ( via my INT 0x24 >handler ) when required. This works well, except that CTRL-C also causes >the handler to be invoked, _BUT_ prints the characters "^C" to something >like stdout or stderr before doing so. > > Now, I don't care whether or not CTRL-C invokes INT 0x24 as long as my >screen _doesn't get corrupted_ ! To this end I have ANSI.SYS redefine > ... You must mean INT 0x23 not 0x24 as 0x24 is for the critical error interrupt. If you really are hooking 0x24 and not 0x23 you should make this change first. However this still won't solve your problem :-(. I've tried three methods to prevent corruption of graphics mode screens when ctrl-C is hit (note I always hook interrupts 0x1B and 0x23 with handlers that do nothing but an IRET). Method 1 was to put stdin and stdout into raw (intead of cooked) mode (using a DOS IOCTL call, INT 0x21 Function 0x44 Subfunction 01) and hoping that DOS wouldn't echo the ctrl-C. This *almost* worked. Somehow stdin got returned to cooked mode as a side effect of some other DOS or BIOS call which I made after the IOCTL call -- I never did have the patience (or the time) to track this down. Method 2 was to actually install my own handler for the keyboard interrupt but my lack of knowledge about programming the keyboard controller caused me some problems in this area. (BTW, can anyone recommend a good source of information for writing keyboard handlers under DOS?). Method 3 worked. I used the standard library routine dup2 to redirect stdout and stderr to a file when my application is in graphics mode, thus preventing screen corruption when control-C is hit (or when some run-time library routine takes an error and decides to do a printf). When I exit graphics mode I delete the temp file. The following sample program demonstrates the idea for stdout (written using Zortech C++ but I expect it would work with Turbo C as well). In fact it was suggested to me by someone on the net... #include <string.h> #include <stdio.h> #include <dos.h> char *temp_file_string1 = "This goes to temp.file (stdout redirected)\n"; char *stdout_string = "This goes to stdout\r\n"; void main() { int newout, oldout; char *tempfile; oldout = dup(1); if ( (tempfile = tmpnam(NULL)) == NULL ) { perror("can't open temp file"); exit(1); } else printf("Opening temp file %s for redirection\n", tempfile); newout = open(tempfile, O_WRONLY|O_CREAT|O_TRUNC, 0777); dup2(newout, 1); write(1, temp_file_string1, strlen(temp_file_string1)); dup2(oldout, 1); write(1, stdout_string, strlen(stdout_string)); } I guess this whole thing with handling ctrl-C/break under DOS is final verification that we spend 95% of our time working on 5% of the software (or however the saying goes :-). Hope this helps. -- Wayne Turner Tektronix, Inc. Redmond, Oregon waynet@kit.CNA.TEK.COM
mazz@jupiter.newcastle.edu.au (Richard Mazzaferri) (04/12/91)
waynet@kit.tek.com (Wayne Turner) writes: >In article <mazz.671291088@jupiter.newcastle.edu.au> mazz@jupiter.newcastle.edu.au (Richard Mazzaferri) writes: [ trying to prevent "^C" from reaching screen, while still allowing CTRL-BREAK to generate it's interrupt - I said INT0x24 when I should have 0x23. ] >You must mean INT 0x23 not 0x24 as 0x24 is for the critical error interrupt. >If you really are hooking 0x24 and not 0x23 you should make this change >first. Yes, sorry - I've also written my critical event handler for INT 0x24, and I'm starting to get memory glitches from all those interrupt handlers - forgetting which one does what. [ Suggestion 1 : Use IOCTL to put stdin into raw mode. ( I'd already tried this. ) Some other DOS/BIOS call apparently puts stdin back into cooked mode. ( I've never tried to track down how/why either. ) ] [ Suggestion 2 : install own handler for keyboard interrupt. Wayne had problems. ( I was hoping not to do this. ) Anyone ever done it? ] [ Suggestion 3 : redirect stderr/stdout to a tempfile using dup2. ( I thought of doing this and thought - No, there must be a better way. ) ] Thanks for the ideas and shared experience. If no-one comes up with a better idea I guess this will have to be implemented. Does anyone actually know how ANSI.SYS redefines keys? Mazz. -- ----------------------------------------------------------------- Richard Mazzaferri, Comp.Sc. Ph.D. student, Uni. of Newcastle, Ph (049) 602574 mazz@nucs.newcastle.edu.au Australia. -----------------------------------------------------------------
iisakkil@vipunen.hut.fi (Mika R Iisakkila) (04/12/91)
One easy method is to simply close stdout. If you still need it somewhere, you might dup() it into some other descriptor before closing the original stdout.
teittinen@cc.helsinki.fi (04/14/91)
In article <mazz.671428317@jupiter.newcastle.edu.au>, mazz@jupiter.newcastle.edu.au (Richard Mazzaferri) writes: > > [ Suggestion 2 : install own handler for keyboard interrupt. Wayne had > problems. ( I was hoping not to do this. ) Anyone ever done it? ] I can't believe it. Nobody has yet posted code to do this. Ok, I guess it is my turn to give source to net. The following is a group of functions for TurboC to disable ctrl-c totally, nothing will come up on the screen. Or actually, you can change the ctrl-c to any scan code you want. But see the listing, it is quite well commented. Hereby I declare the following source file public domain :-). You can use it, but don't claim it to be yours. Keep the comments in it. -------8<-------clip here-------8<------- /***************************************************************************/ /* */ /* Module CtrlC */ /* */ /* Filename: CTRLC.C */ /* Date: 18.09.1989 */ /* Version: 1.0 */ /* Author: Marko Teittinen */ /* */ /* This module contains functions to disable ctrl-c checking */ /* */ /* This file is public domain, you may copy, use and modify it, but */ /* don't claim it to be yours. Don't remove comments, and comment your */ /* modifications. */ /* */ /***************************************************************************/ /* Include files */ #include <dos.h> /***************************************************************************/ /* Type definitions */ typedef unsigned int word; typedef unsigned char byte; /***************************************************************************/ /* Constant definitions */ #define cScan 0x2E /* Scan code for the "C" key */ #define CtrlOff 0xFB /* Ctrl-C bit mask */ #define CtrlOn 0x04 /* Ctrl-C bit mask */ /***************************************************************************/ /* Macro definitions */ /* Get lower byte or word of a variable */ #define LOBYTE(x) ((byte)((word) x & 0x00FF)) #define LOWORD(x) ((word)((unsigned long) x & 0x0000FFFF)) /* Test if specified bit is set */ #define BITSET(x,n) ((word)x & (0x0001 << n)) /***************************************************************************/ /* Function prototypes and short documentation */ void DisableCtrlC(word ScanCode); /* Disables Ctrl-C interrupts */ /* Given ScanCode will replace every Ctrl-C pressed */ void EnableCtrlC(void); /* Restores original keyboard, Ctrl-C and Ctrl-Break interrupts */ /***************************************************************************/ /* Static variables */ /* Ptr to original kbd handler */ static void (interrupt far *OrigInt09)(void); /* Ptr to original ^C handler */ static void (interrupt far *OrigInt1B)(void); /* Ptr to original brk handler */ static void (interrupt far *OrigInt23)(void); /* Pointer to keyboard buffer */ static word far *KbdBuf = (word far *)0x0040001EL; /* Pointer to keyboard control flag byte */ static word far *KbdCtrl = (word far *)0x00400017L; /* Pointer to keyboard buffer tail pointer */ static word far *KbdTail = (word far *)0x0040001CL; /* Value to replace Ctrl-C in keyboard buffer */ static word Value; /***************************************************************************/ /* New keyboard interrupt */ static void interrupt far Keyboard(void) { word Data, /* Data from Kbd port 60h */ CtrlC, /* CtrlC = 1, if ^C was pressed else CtrlC = 0 */ Indx; disable(); /* Read the data from kbd port 0x60 */ Data = inp(0x60); /* Test if Ctrl is pressed and C is pressed */ if (BITSET(*KbdCtrl,2) && LOBYTE(Data) == cScan) { /* Ctrl-C was pressed */ CtrlC = 1; /* Get the current position of the keyboard buffer */ Indx = (*KbdTail - LOBYTE(LOWORD(KbdBuf))) / 2; /* Lie to original interrupt that Ctrl was not pressed */ *KbdCtrl &= CtrlOff; } else CtrlC = 0; /* Call the original keyboard interrupt */ OrigInt09(); if (CtrlC) { /* Restore the Ctrl-flag in keyboard control flag */ *KbdCtrl |= CtrlOn; /* Replace Ctrl-C with the value defined */ KbdBuf[Indx] = Value; } } /***************************************************************************/ /* New interrupt for Ctrl-Break and Ctrl-C */ static void interrupt far DoNothing(void) { /* Do nothing */ } /***************************************************************************/ /* Disable Ctrl-C interrupts */ void DisableCtrlC(word ScanCode) { OrigInt09 = getvect(0x09); /* Save original keyboard interrupt */ OrigInt1B = getvect(0x1B); /* Save original Ctrl-C interrupt */ OrigInt23 = getvect(0x23); /* Save original Ctrl-Break interrupt */ setvect(0x09, Keyboard); /* Install our own keyboard interrupt */ setvect(0x1B, DoNothing); /* Install our own Ctrl-C interrupt */ setvect(0x23, DoNothing); /* Install our own Ctrl-Break interrupt */ Value = ScanCode; } /***************************************************************************/ /* Enable Ctrl-C interrupts */ void EnableCtrlC(void) { setvect(0x09, OrigInt09); /* Restore original keyboard interrupt */ setvect(0x1B, OrigInt1B); /* Restore original Ctrl-C interrupt */ setvect(0x23, OrigInt23); /* Restore original Ctrl-Break interrupt */ } /***************************************************************************/ /* End of file */ -------8<-------clip here-------8<------- -- E-Mail: teittinen@finuh.bitnet ! "Studying is the only way teittinen@cc.helsinki.fi ! to do nothing without Marko Teittinen, student of computer science ! anyone blaming you" -me