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-------------------