Detabbed
[AROS.git] / rom / dos / exit.c
blob3891b76f424ee3a5410fe039be8c4fc9e6d19af0
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include <aros/debug.h>
10 #include <setjmp.h>
12 #include "dos_intern.h"
15 * On m68k exiting a program can be performed by setting SP
16 * to (FindTask(NULL)->pr_ReturnAddr - 4), and performing an rts.
18 * For the complete code, see arch/m68k-amiga/dos/exit.c and
19 * arch/m68k-amiga/dos/bcpl.S, "BCPL Exit"
21 * pr_ReturnAddr points to the actual stack size.
23 * Similar construction should work on all CPUs. I guess this is what
24 * is used by Exit() routine.
26 * For other CPUs we don't keep exact stack layout and consider it
27 * private. Only Exit() knows what to do with it. However we keep stack
28 * size value where it was, some code relies on it.
30 struct StackState
32 IPTR stackSize;
33 APTR stackLower;
34 APTR stackUpper;
35 ULONG retval;
36 jmp_buf state;
39 /*****************************************************************************
41 NAME */
42 #include <proto/dos.h>
44 AROS_LH1(void, Exit,
46 /* SYNOPSIS */
47 AROS_LHA(LONG, returnCode, D1),
49 /* LOCATION */
50 struct DosLibrary *, DOSBase, 24, Dos)
52 /* FUNCTION
53 Instantly terminate the program.
55 INPUTS
56 returnCode - Process' return code.
58 RESULT
59 None.
61 NOTES
62 Calling this function bypasses normal termination sequence of your program.
63 Automatically opened libraries will not be closed, destructors will not be
64 called, etc. Do this only if you really know what are you doing. It's not
65 adviced to use this function at all.
67 EXAMPLE
69 BUGS
71 SEE ALSO
73 INTERNALS
75 *****************************************************************************/
77 AROS_LIBFUNC_INIT
79 struct Process *me = (struct Process *)FindTask(NULL);
80 struct StackState *ss;
82 ASSERT_VALID_PROCESS(me);
83 ss = me->pr_ReturnAddr;
85 /* Return code can be zero, so we can't pass it via longjmp() */
86 ss->retval = returnCode;
88 /* Close dos.library because the program has opened it in order to obtain DOSBase */
89 CloseLibrary(&DOSBase->dl_lib);
91 /* Disable() because we may have to swap stack limits */
92 Disable();
93 longjmp(ss->state, 1);
95 AROS_LIBFUNC_EXIT
96 } /* Exit */
99 * CallEntry() is also defined here because it is closely associated with
100 * Exit() implementation.
101 * For different CPUs we may have optimized versions of these two functions in asm.
103 ULONG CallEntry(STRPTR argptr, ULONG argsize, LONG_FUNC entry, struct Process *me)
105 struct StackState ss;
107 /* Set the first IPTR to something like on AmigaOS(tm) */
108 ss.stackSize = (APTR)&ss - me->pr_Task.tc_SPLower;
109 /* Remember stack limits for Exit() */
110 ss.stackLower = me->pr_Task.tc_SPLower;
111 ss.stackUpper = me->pr_Task.tc_SPUpper;
112 me->pr_ReturnAddr = &ss;
114 if (setjmp(ss.state))
117 * We came here from Exit().
118 * Restore stack limits because the program might have swapped stack.
119 * We are clever enough to recover from this.
121 me->pr_Task.tc_SPLower = ss.stackLower;
122 me->pr_Task.tc_SPUpper = ss.stackUpper;
124 Enable(); /* We Disable()d in Exit() */
126 return ss.retval;
128 else
129 return AROS_UFC3(ULONG, entry,
130 AROS_UFCA(STRPTR, argptr, A0),
131 AROS_UFCA(ULONG, argsize, D0),
132 AROS_UFCA(struct ExecBase *, SysBase, A6));