home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * onexit.c - Copyright (C) 1989 by Symantec Corp. All rights reserved.
- *
- * Shutdown routines installed with "onexit" are called only on NORMAL
- * termination, i.e. calling "exit" or returning from "main".
- *
- * Shutdown routines installed with "_onexit" are called on "ExitToShell"
- * as well as on normal termination.
- *
- * When initiating any other form of termination (e.g. "Launch"), the
- * user can call "_exiting" to force shutdown routines to be called.
- *
- */
-
- #ifndef _MacTypes_
- #include <MacHeaders>
- #endif
-
- extern long ATrapHandler : 0x28;
-
- typedef void (*Proc)();
-
- Proc onexit(Proc);
- Proc _onexit(Proc);
- void _exiting(int);
- void exit(int);
- void nop(void);
- void abort(void);
-
- #define NPROCS 32
-
- static struct proc { Proc proc; int always; } procs[NPROCS];
- static int next = 0;
- static Proc oldexit, oldES;
- static char *ptrES;
-
- static void normal_exit(void), newES(void);
-
-
- /*
- * exit - normal program termination
- *
- * The exit status is ignored.
- *
- */
-
- void
- exit(i)
- {
- asm {
- movea.l 0x6C(a5),a0
- jsr (a0) ; call onexit vector
- _ExitToShell
- }
- }
-
-
- /*
- * onexit - install user shutdown routine
- *
- */
-
- Proc
- onexit(proc)
- Proc proc;
- {
- register struct proc *p;
-
- if (next == NPROCS)
- return(0);
-
- /* install proc in table */
-
- p = &procs[next++];
- p->proc = proc;
- /* p->always = 0; */
- if (!oldexit) {
- proc = normal_exit;
-
- /* install onexit vector */
-
- asm {
- move.l 0x6C(a5),oldexit
- move.l proc,0x6C(a5)
- }
- }
- return(p->proc);
- }
-
-
- /*
- * normal_exit - onexit vector
- *
- */
-
- static void
- normal_exit()
- {
- _exiting(1);
- }
-
-
- /*
- * _onexit - install a critical shutdown routine
- *
- * Routines installed with "_onexit" are called even if the program does
- * not terminate normally, provided only that "ExitToShell" is called.
- *
- */
-
- Proc
- _onexit(proc)
- Proc proc;
- {
- register struct proc *p;
-
- if (next == NPROCS)
- return(0);
-
- /* install proc in table */
-
- p = &procs[next++];
- p->proc = proc;
- p->always = 1;
- if (!oldES) {
- proc = newES;
-
- /* save original ExitToShell */
-
- asm {
- move.w #0xA9F4,d0 ; _ExitToShell
- _GetTrapAddress
- move.l a0,oldES
- }
-
- /* (64K ROM only) allocate intercept in sysheap */
-
- asm {
- movea.l proc,a0
- tst.w ROM85
- bpl.s @1
- moveq #6,d0
- _NewPtr SYS
- move.l a0,ptrES
- move.w #0x4EF9,(a0) ; JMP abs.L
- move.l proc,2(a0)
- @1 }
-
- /* install ExitToShell intercept */
-
- asm {
- move.w #0xA9F4,d0 ; _ExitToShell
- _SetTrapAddress
- }
- }
- return(p->proc);
- }
-
-
- /*
- * newES - ExitToShell intercept
- *
- */
-
- static void
- newES()
- {
- _exiting(0);
- ExitToShell();
- }
-
-
- /*
- * _exiting - perform shutdown activity
- *
- * The argument controls which shutdown routines should be called:
- *
- * _exiting(1) call all installed shutdown routines
- * _exiting(0) call only routines installed with "_onexit"
- *
- */
-
- void
- _exiting(normally)
- {
- register struct proc *p;
- Proc proc;
- int i;
-
- SetUpA5();
- p = &procs[NPROCS];
- for (i = NPROCS; i--; ) {
- if (proc = (--p)->proc) {
- p->proc = 0;
- if (normally || p->always)
- (*proc)();
- }
- }
-
- /* deallocate ExitToShell intercept */
-
- asm {
- move.l ptrES,d0
- beq.s @1
- movea.l d0,a0
- _DisposPtr
- clr.l ptrES
- @1 }
-
- /* remove ExitToShell intercept */
-
- asm {
- move.l oldES,d0
- beq.s @2
- movea.l d0,a0
- move.w #0xA9F4,d0
- _SetTrapAddress
- clr.l oldES
- @2 }
-
- /* call original exit proc */
-
- asm {
- movea.l 0x6C(a5),a0
- move.l oldexit,d0
- beq.s @3
- movea.l d0,a0
- @3 jsr (a0)
- }
- oldexit = nop;
- RestoreA5();
- }
-
-
- /*
- * nop - do nothing
- *
- */
-
- static void
- nop()
- {
- }
-
-
- /*
- * abort - abort execution
- *
- * A debugger trap is issued if it looks like a debugger is installed.
- *
- */
-
- void
- abort()
- {
- if (GetTrapAddress(0xA055) == GetTrapAddress(0xA89F)) {
- if ((ATrapHandler & Lo3Bytes) < ((long) ROMBase & Lo3Bytes))
- Debugger();
- }
- else {
- if (StripAddress(ATrapHandler) < StripAddress(ROMBase))
- Debugger();
- }
- ExitToShell();
- }
-