diff --git a/libmaxsi/Makefile b/libmaxsi/Makefile index 3e6f3bb3..6fcd0eed 100644 --- a/libmaxsi/Makefile +++ b/libmaxsi/Makefile @@ -45,6 +45,7 @@ ioleast.o \ terminal.o \ kernelinfo.o \ init.o \ +exit.o \ signal.o \ $(CPU)/signal.o \ $(CPU)/fork.o \ diff --git a/libmaxsi/exit.cpp b/libmaxsi/exit.cpp new file mode 100644 index 00000000..e6ea30d0 --- /dev/null +++ b/libmaxsi/exit.cpp @@ -0,0 +1,62 @@ +/******************************************************************************* + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + + This file is part of LibMaxsi. + + LibMaxsi is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + + You should have received a copy of the GNU Lesser General Public License + along with LibMaxsi. If not, see . + + exit.cpp + Hooks that is called upon process exit. + +*******************************************************************************/ + +#include + +struct exithandler +{ + void (*hook)(int, void*); + void* param; + struct exithandler* next; +}* exit_handler_stack = NULL; + +extern "C" int on_exit(void (*hook)(int, void*), void* param) +{ + struct exithandler* handler = (struct exithandler*) malloc(sizeof(struct exithandler)); + if ( !handler ) { return -1; } + handler->hook = hook; + handler->param = param; + handler->next = exit_handler_stack; + exit_handler_stack = handler; + return 0; +} + +static void atexit_adapter(int /*status*/, void* user) +{ + ((void (*)(void)) user)(); +} + +extern "C" int atexit(void (*hook)(void)) +{ + return on_exit(atexit_adapter, (void*) hook); +} + +extern "C" void call_exit_handlers(int status) +{ + while ( exit_handler_stack ) + { + exit_handler_stack->hook(status, exit_handler_stack->param); + exit_handler_stack = exit_handler_stack->next; + } +} diff --git a/libmaxsi/include/stdlib.h b/libmaxsi/include/stdlib.h index 92cfb470..76b47c48 100644 --- a/libmaxsi/include/stdlib.h +++ b/libmaxsi/include/stdlib.h @@ -49,6 +49,7 @@ typedef int div_t, ldiv_t, lldiv_t; void abort(void); int abs(int value); +int atexit(void (*function)(void)); int atoi(const char*); long atol(const char*); long long atoll(const char*); @@ -62,6 +63,7 @@ void* malloc(size_t); #if !defined(_SORTIX_SOURCE) char* mktemp(char* templ); #endif +int on_exit(void (*function)(int, void*), void* arg); int putenv(char*); void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); int rand(void); @@ -93,7 +95,6 @@ int clearenv(void); /* TODO: These are not implemented in libmaxsi/sortix yet. */ #if defined(__SORTIX_SHOW_UNIMPLEMENTED) long a64l(const char* s); -int atexit(void (*function)(void)); double atof(const char* value); void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*)); div_t div(int, int); diff --git a/libmaxsi/process.cpp b/libmaxsi/process.cpp index 30cd9a85..0c1a7c00 100644 --- a/libmaxsi/process.cpp +++ b/libmaxsi/process.cpp @@ -174,8 +174,11 @@ namespace Maxsi return result; } + extern "C" void call_exit_handlers(int status); + DUAL_FUNCTION(void, exit, Exit, (int status)) { + call_exit_handlers(status); dcloseall(); fcloseall(); _exit(status);