home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Zodiac Super OZ
/
MEDIADEPOT.ISO
/
FILES
/
16
/
FREEDOS.ZIP
/
FD_A4PRE.ZIP
/
SOURCE
/
FD10.ZIP
/
ctrl_c.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-15
|
10KB
|
399 lines
/*
* * ctrl_c.c *
*
* Author: John Galvin * Date: 25-Jul-1988 * Purpose: trap
* Ctrl-C and Ctrl-Break without printing anything. *
*
* Note: * Use of these routines will prevent Ctrl-C and
* Ctrl-Break * from terminating your program. They will also
* prevent * Ctrl-P, Ctrl-S, and Ctrl-Z from being interpreted by *
* MS-DOS as they normally are. Your program will be able * to read
* *all* of these characters, so if you don't want * them in your
* input stream, you will have to do something * about them
* yourself. This code was written to work in * all standard memory
* models of the Microsoft C compiler * version 5.1. Do not use
* getch() or getche() with these * routines. See the #ifdef'd
* section of code below for an * example of how to use these
* functions. *
*
* Copyright (c) 1988 by John W. Galvin. All Rights Reserved. *
*
* Permission is hereby granted by the author for anyone to use this *
* code in their own programs provided the following conditions are met: *
* This copyright notice is left intact. Any changes to this text/code *
* must be commented and credited to the correct author somewhere * in
* this file. *
*
* $Log: ctrl_c.c $ * Revision 1.1 88/07/25 22:04:46 galvin *
* Initial revision *
*
*
*/
#ifndef _lint
static char *rcsid = "$Id: ctrl_c.c 1.1 88/07/25 22:04:46 galvin Exp $";
#endif
#include <stdio.h>
#include <file.h>
#include <freedos.h>
#include <portable.h>
#include "ctrl_c.h"
#define BREAKINTR 27
#define DOS 33
#define CTRLCCHK 0x33
#define GETVECT 53
#define SETVECT 37
#define IOCTL 0x44
#define DEVFLAG 0x80
#define RAWFLAG 0x20
#define cflag 0x0001
void do_intcpt(void);
static void do_break(int op);
/*
* * Name: *
*
* get_ctrl_c_chk() - return status of MS-DOS Ctrl-C checking. *
*
* Synopsis: *
*
* int get_ctrl_c_chk() *
*
* Description: *
*
* This function determines the current level of Ctrl-C *
* checking being performed by MS-DOS. The effect of this *
* function is roughly analagous to issuing a "BREAK" command * at
* the MS-DOS command prompt. *
*
* Return Values: *
*
* This function returns FALSE if MS-DOS is only checking for *
* Ctrl-C in the 0x01 - 0x0C group of int 0x21 functions, or * if an
* error occurred. A return of TRUE indicates that MS-DOS * is
* checking for Ctrl-C before each DOS service is performed. *
*
* Bugs: *
*
*
*
*/
int
get_ctrl_c_chk(void)
{
USEREGS
_AX = CTRLCCHK << 8 | GET;
if (geninterrupt(DOS) & cflag)
return FALSE;
else
return _DL;
}
/*
* * Name: *
*
* set_ctrl_c_chk() - set the level of MS-DOS Ctrl-C checking. *
*
* Synopsis: *
*
* int set_ctrl_c_chk(value) * int value; *
*
* Description: *
*
* This function sets the level of Ctrl-C checking that MS-DOS *
* will perform. Value should be one of the two manifest *
* constants CHKON or CHKOFF. Calling set_ctrl_c_chk() with a *
* value of CHKON is equivalent to issuing a "BREAK ON" command * at
* the MS-DOS command line. Calling set_ctrl_c_chk() with a * value
* of CHKOFF is equivalent to issuing a "BREAK OFF" command * at the
* MS-DOS command line. *
*
* Return Values: *
*
* This function returns FALSE if an error occurred, TRUE otherwise. *
*
* Bugs: *
*
*
*
*/
int
set_ctrl_c_chk(int value)
{
USEREGS
_AX = CTRLCCHK << 8 | SET;
_DX = _DH << 8 | value;
return !(geninterrupt(DOS) & cflag);
}
/*
* * Name: *
*
* ioctl() - MS-DOS i/o control for devices interface. *
*
* Synopsis: *
*
* unsigned int ioctl(handle, op, value) * int
* handle; * int op; * unsigned int value; *
*
* Description: *
*
* This routine provides a limited interface to the MS-DOS *
* ioctl functions. It primarily intended to get/set the * device
* attribute bits for a file handle. Handle should * an open file
* handle (hopefully for a device). Op should * be one of SET or
* GET. If op is SET, the device attribute * bits for handle will
* be set to those specified in value. *
*
* Return Values: *
*
* This function returns FALSE if an error occurred. Otherwise *
* The new device attribute word will be returned. The attribute *
* word may possibly be equal to FALSE. *
*
* Bugs: *
*
*
*
*/
word
ioctl(int handle, int op, word value)
{
USEREGS
_AX = IOCTL << 8 | op;
_BX = handle;
_DX = value & 0x00FF;
if (geninterrupt(DOS) & cflag)
return FALSE;
else
return _DX;
}
/*
* * Name: *
*
* rawio() - set/reset a device to/from raw i/o mode. *
*
* Synopsis: *
*
* int rawio(handle, raw) * int handle; *
* int raw; *
*
* Description: *
*
* Rawio() uses ioctl() to set/reset a device to/from raw i/o *
* mode. When a device is in raw mode, and Ctrl-C checking is *
* turned off, Ctrl-C, Ctrl-S, Ctrl-P, and Ctrl-Z may be read * as
* data without having MS-DOS interpret them. Handle must * refer
* to an open file/device. If raw is TRUE, the device * will be set
* to raw mode. Otherwise, the device will be reset * from raw
* mode. *
*
* Return Values: *
*
* This function returns a non-zero value if the device was *
* in raw mode, 0 otherwise. *
*
* Bugs: *
*
* No checks are made for errors from ioctl().
*/
int
rawio(int handle, int raw)
{
word flags;
flags = ioctl(handle, GET, 0);
if (flags & DEVFLAG) {
if (raw)
ioctl(handle, SET, flags | RAWFLAG);
else
ioctl(handle, SET, flags & ~RAWFLAG);
}
return (flags & RAWFLAG);
}
/*
* * Name: *
*
* do_intcpt() - Ctrl-Break Interrupt (0x1B) routine. *
*
* Synopsis: *
*
* void interrupt cdecl far do_intcpt() *
*
* Description: *
*
* This routine is the dummy interrupt routine which is used *
* to intercept the IBM PC Break interrupt. *
*
* Return Values: *
*
* None. *
*
* Bugs: *
*
*
*
*/
void
do_intcpt(void)
{
asm
{
POP BP
IRET
}
}
/*
* * Name: *
*
* do_break() - intercept/release the IBM PC Break Interrupt. *
*
* Synopsis: *
*
* static void do_break(op) * int op; *
*
* Description: *
*
* If passed the manifest constant INTERCEPT, this routine *
* will use do_intcpt() to intercept the IBM PC Ctrl-Break *
* interrupt. If this routine is not used while trapping * Ctrl-C
* and Ctrl-Break, a ^C may turn up *after* the porgram * exits.
* When passed the manifest constant RELEASE, do_break() * will
* de-install its interrupt handler. *
*
* Return Values: *
*
* None. *
*
* Bugs: *
*
* No error checks are performed on the returns of int86x().
*/
word oldseg;
word oldofs;
static void
do_break(int op)
{
word ds;
if (op == INTERCEPT) {
asm
{
MOV AH, GETVECT
MOV AL, BREAKINTR
INT DOS
MOV _oldseg, ES
MOV _oldofs, BX
MOV DX, OFFSET _do_intcpt
MOV asmName(ds, -2), CS
}
} else {
asm
{
MOV DX, _oldofs
MOV AX, _oldseg
MOV asmName(ds, -2), AX
}
}
asm
{
PUSH DS
MOV DS, asmName(ds, -2)
MOV AH, SETVECT
MOV AL, BREAKINTR
INT DOS
POP DS
}
}
/*
* * Name: *
*
* ctrl_c() - nullify Ctrl-C and Ctrl-Break. *
*
* Synopsis: *
*
* int ctrl_c(op) * int op; *
*
* Description: *
*
* If passed the manifest constant INTERCEPT, ctrl_c() will *
* prevent MS-DOS from interpreting Ctrl-C, Ctrl-Break, Ctrl-P, *
* Ctrl-S, and Ctrl-Z as it normally does. I.E. a Ctrl-C or *
* Ctrl-Break will not cause a ^C to be output and will not * abort
* the program. Do not use getch(), or getche() while * this
* routine is in effect, they do not properly support * this mode.
* If passed the manifest constant RELEASE, ctrl_c() * will return
* the Ctrl character interpretation that existed * before
* ctrl_c(INTERCEPT) was called. *
*
* Return Values: *
*
* Ctrl_c() always returns TRUE. *
*
* Bugs: *
*
* No error checking is done.
*/
int
ctrl_c(int op)
{
static word outflg;
static word inflg;
static word ctrlcchk;
if (op == INTERCEPT) {
do_break(INTERCEPT);
inflg = rawio(fileno(stdin), TRUE);
outflg = rawio(fileno(stdout), TRUE);
if ((ctrlcchk = get_ctrl_c_chk()) == CHKON)
set_ctrl_c_chk(CHKOFF);
} else {
set_ctrl_c_chk(ctrlcchk);
rawio(fileno(stdout), outflg);
rawio(fileno(stdin), inflg);
do_break(RELEASE);
}
return (TRUE);
}
#ifdef CTRL_CDEBUG
#include <video.h>
int
main()
{
int achar;
ctrl_c(INTERCEPT);
vopen();
while ((achar = kbget() & 0xFF) != ' ')
vputc(achar);
ctrl_c(RELEASE);
exit(0);
}
#endif