From 850544349cb693d9e50a35d3ab0304da07f59ae2 Mon Sep 17 00:00:00 2001 From: Lephe Date: Sat, 29 May 2021 16:29:50 +0200 Subject: [PATCH] kernel: implement _Exit to support exit --- src/kernel/start.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/kernel/start.c b/src/kernel/start.c index 536b591..8f793bd 100644 --- a/src/kernel/start.c +++ b/src/kernel/start.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "kernel.h" @@ -46,6 +48,12 @@ void gint_setrestart(int restart) gint_restart = restart; } +/* Jumping there will properly unwind and leave the add-in (CASIOWIN does not + have an exit syscall and simply wants you to return from main()) */ +jmp_buf gint_exitbuf; +/* Return value of main() */ +static int gint_exitcode; + /* regcpy(): Copy a memory region using symbol information @l Source pointer (load address) @s Size of area (should be a multiple of 16) @@ -173,18 +181,22 @@ int start(int isappli, int optnum) hosted user application, which has its own constructors and destructors to work with. */ - callarray(&bctors, &ectors); - - int rc = 1; while(1) { - rc = main(isappli, optnum); + /* Here, we use exit() to allow the standard library to do + what it wants in exit() after main() finishes executing */ + if(!setjmp(gint_exitbuf)) { + callarray(&bctors, &ectors); + exit(main(isappli, optnum)); + } + else { + callarray(&bdtors, &edtors); + } + if(!gint_restart) break; gint_osmenu(); } - callarray(&bdtors, &edtors); - /* Before leaving the application, we need to clean everything we changed to hardware settings and peripheral modules. The OS is bound to be confused (and hang, or crash, or any other kind of giving up) @@ -193,5 +205,12 @@ int start(int isappli, int optnum) /* Unload gint and give back control to the system. Driver settings will be restored while interrupts are disabled */ kquit(); - return rc; + return gint_exitcode; +} + +/* Standard _Exit, used by the fxlibc exit() to leave control */ +void _Exit(int rc) +{ + gint_exitcode = rc; + longjmp(gint_exitbuf, 1); }