home *** CD-ROM | disk | FTP | other *** search
- /* atfinish -- register functions to be called on termination */
- /* copyright 1987 Michael M Rubenstein */
-
- /* unlike atexit, atfinish functions will be run on any kind of termination */
-
- #include <dos.h>
- #include "atfinish.h"
-
- #define MAXFINISH 8
-
- static void far (*old_quit)(void) = (void far (*) ()) 0;
- static unsigned holdss, holdsp;
- static void interrupt quit();
- static void (*func[MAXFINISH])(void);
- static int nfunc = 0;
-
- extern unsigned _psp;
-
- int atfinish(void (*f)())
- {
- if (nfunc == MAXFINISH)
- return 1;
-
- /* get old exit routine */
- if (old_quit == (void far (*)()) 0)
- old_quit = MK_FP(peek(_psp, 12), peek(_psp, 10));
-
- disable();
- holdss = _SS; /* quit routine will need to use our stack */
- holdsp = _SP;
- poke(_psp, 10, FP_OFF(quit)); /* set our quit routine */
- poke(_psp, 12, FP_SEG(quit));
- enable();
-
- func[nfunc] = f;
- ++nfunc;
-
- return 0;
- }
-
- /* quit routine. this routine is executed on any termination */
- void interrupt quit(void)
- {
- static int i;
-
- disable();
- _SP = holdsp; /* set to our stack. this is safe since we're not */
- _SS = holdss; /* returning. */
- enable();
-
- for (i = 0; i < nfunc; ++i)
- (*func[i])();
-
- (*old_quit)(); /* go to old termination address (never returns) */
- }
-