Path: utzoo!utgpu!water!watmath!clyde!bellcore!rutgers!rochester!udel!mmdf From: iphwk%MTSUNIX1.BITNET@cunyvm.cuny.edu (Bill Kinnersley) Newsgroups: comp.sys.amiga Subject: Sample Exception Handler Message-ID: <3447@louie.udel.EDU> Date: 24 Jul 88 03:41:45 GMT Sender: mmdf@udel.EDU Lines: 118 Well, I guess I answered my own question out of necessity. Here is my attempt at writing an Exception Handler. The program will loop indefinitely, and catch the signals that result from typing either ^C, ^D, ^E, or ^F. In addition, ^C will abort the program. If people out there with experience in these matters see any mistakes I've made, please let me know.. Bill Kinnersley Physics Department BITNET: iphwk@mtsunix1 Montana State University INTERNET: iphwk%mtsunix1.bitnet@cunyvm.cuny.edu Bozeman, MT 59717 CSNET: iphwk%mtsunix1.bitnet@relay.cs.net (406)994-3614 UUCP: ...psuvax1!mtsunix1.bitnet!iphwk "He learned to communicate with birds and discovered that their conversation was fantastically boring. It was all to do with wind speed, wingspan, power-to-weight ratios and a fair bit about berries." ---------------- /* An illustration of how to write an Exception Handler */ /* Bill Kinnersley - IPHWK@MTSUNIX1.BITNET - 7/23/88 */ /* Compiled using Aztec 3.4a, 16-bit integers. */ /* ^D, ^E, ^F will print a message, ^C will abort. */ #include #include #include #include #include extern short Enable_Abort; long aborted, cursigs, mysigs, oldsigs; struct Task *mytask; main() { /* Install my handler */ install(); /* Make sure that Aztec does not catch any ^C's */ Enable_Abort = 0; /* Busy loop simulating something useful... */ /* Note that each Exception DOES break into this loop. */ /* The aborted flag is polled only because */ /* I want to generate a clean exit from main(), */ /* not try to call cleanup from inside the handler. */ while (!aborted) {} /* It's essential to put things back the way they were */ /* Exceptions are task-specific, but all programs run */ /* from the same CLI will reuse the same Task structure */ cleanup(); } APTR oldcode; install() { int face(); mysigs = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F; mytask = FindTask(0L); /* Don't anyone else bother me while I'm changing my Task structure */ Forbid(); /* Save the old Exception Handler and install my own */ oldcode = mytask->tc_ExceptCode; mytask->tc_ExceptCode = (APTR)face; /* I won't use the tc_ExceptData field...leave it unchanged */ Permit(); /* Save the old Exception signals so we can put them back later */ oldsigs = SetExcept(mysigs, mysigs); } cleanup() { /* Restore the previous Exception Handler (ROM-wack?) */ Forbid(); mytask->tc_ExceptCode = oldcode; Permit(); SetExcept(0L,mysigs); } #asm _face: ;the signals will be passed to me in d0 move.l d0,-(a7) ;restore a4, which points to Aztec's small data segment */ public _geta4 jsr _geta4 move.l (a7)+,_cursigs jsr _hdlr ;return signals to the system so they can be reset move.l _cursigs,d0 rts #endasm hdlr() { /* Note that even AmigaDOS stuff can be done from here */ printf("Exception %lx Control-",cursigs); if (cursigs & SIGBREAKF_CTRL_C) {printf("C\n"); aborted=1;} if (cursigs & SIGBREAKF_CTRL_D) printf("D\n"); if (cursigs & SIGBREAKF_CTRL_E) printf("E\n"); if (cursigs & SIGBREAKF_CTRL_F) printf("F\n"); }