kent@ncoast.UUCP (05/04/87)
[ LINE EATER LINE EATER - (I don't really know why people do this) ]
The following is a simple implementation of signal, which seemed to
be missing from the Datalight C library. It implements only the
SIGINT signal, which is the only one that makes any sense under
MSDOS, unless you have support from the floating point library.
----------------------------SIGNAL.MAN----------------------------------------
signal
Summary
int (*signal(sig,func))()
int sig; int (*func)();
Description
The signal function allows a program to handle an interrupt event
generated by the operating system. The only signal implemented here
is SIGINT, which for MSDOS means that the user has typed a
<control-C> or <control-break> character.
The 'func' parameter specifies how the program wishes to respond to
the event specified by 'sig.' The three options for handling the
SIGINT event are :
1) SIG_DFL - The program is terminated and control is returned to the
command interpreter.
2) SIG_IGN - The interrupt event is ignored. In the case of MS-DOS,
a '^C' is echoed to the console, but program execution continues
normally.
3) A user defined function may be specified. Control is passed to
the specified function when the event occurs. The function can then
do whatever is necessary to respond to the event - It can simply
return, call 'exit', or call 'longjmp' to transfer control back to a
location previously specified by 'setjmp.'
Example
#include <stdio.h>
#include <signal.h>
int onintr()
{
signal(SIGINT,SIG_IGN);
printf("Break caught\n");
exit(0);
}
main()
{
signal(SIGINT,onintr);
while(EOF != getchar());
}
----------------------------SIGNAL.H------------------------------------------
/* signal.h - Header for signal function for Datalight C */
#define SIGINT 0
#define SIG_DFL (int (*) ()) 0
#define SIG_IGN (int (*) ()) 1
#define SIG_ILL (int (*) ()) -1
extern int (*signal(int,int (*)()))();
/* end of signal.h */
----------------------------SIGNAL.C------------------------------------------
/* signal.c - signal package for Datalight C */
#ifdef TEST
#include <stdio.h>
#endif
#include <signal.h>
#include <dos.h>
static int (*brk_sig)() = SIG_DFL;
extern void _sig_hand();
int (*signal(sig,func))()
int sig; int (*func)();
{
int (*oldsig)() = brk_sig;
static unsigned offset = 0xFFFF,segment = 0xFFFF;
if (sig != SIGINT)
return SIG_ILL;
/* if we're supposed to let dos do what it wants */
if (func == SIG_DFL)
{
/* if we've never installed our handler */
if (offset == 0xFFFF && segment == 0xFFFF)
return SIG_DFL;
/* otherwise, restore the handler stored in offset and segment */
int_setvector(0x23,offset,segment);
return oldsig;
}
if (func == SIG_IGN)
{
brk_sig = SIG_IGN;
if (offset == 0xFFFF && segment == 0xFFFF)
{
/* need to install our handler */
struct SREGS segregs;
segread(&segregs); /* pick up segment values */
int_getvector(0x23,&offset,&segment); /* get old handler */
int_setvector(0x23,_sig_hand,segregs.cs);
return oldsig;
}
else
return oldsig;
}
/* otherwise install the specified function */
if (offset == 0xFFFF && segment == 0xFFFF)
{
/* need to install our handler */
struct SREGS segregs;
segread(&segregs); /* pick up segment values */
int_getvector(0x23,&offset,&segment); /* get old handler */
int_setvector(0x23,_sig_hand,segregs.cs);
}
brk_sig = func;
return oldsig;
}
void _c_sig_hand()
{
int (*oldsig)() = brk_sig;
if (brk_sig == SIG_IGN)
return;
if (brk_sig == SIG_DFL)
_exit(1);
signal(SIGINT,SIG_DFL); /* reset the handler */
(*oldsig)(); /* call the handler */
}
#ifdef TEST
int onintr()
{
signal(SIGINT,SIG_IGN);
printf("Break caught\n");
exit(0);
}
main()
{
signal(SIGINT,onintr);
while(EOF != getchar());
}
#endif
/* end of signal.c */
----------------------------SIGHAND.ASM---------------------------------------
;;
;; sighand.asm - assembly level 'glue' for signal package
;;
include macros.asm
SIG_IGN equ 1
begcode
begdata
enddata
if LCODE
extrn _c_sig_hand:far
else
extrn _c_sig_hand:near
endif
public _sig_hand
if LCODE
_sig_hand proc far
else
_sig_hand proc near
endif
push ax
push bx
push cx
push dx
push si
push si
push di
push es
push ds
mov ax,dgroup
mov ds,ax
call _c_sig_hand
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
_sig_hand endp
endcode
end
;;
;; end of sighand.asm
;;
----------------------------END OF DATALIGHT SIGNAL PACKAGE-------------------