diff --git a/libc/Makefile b/libc/Makefile index 6d638172..ab4fd390 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -328,6 +328,7 @@ stdio/tmpnam.o \ stdio/vfprintf.o \ stdio/vprintf.o \ stdio/vscanf.o \ +stdlib/atexit.o \ stdlib/canonicalize_file_name_at.o \ stdlib/canonicalize_file_name.o \ stdlib/env.o \ diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 458874b6..5c3f06ea 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -128,6 +128,16 @@ char* getenv(const char*); int clearenv(void); #endif +#if __is_sortix_libc +struct exit_handler +{ + void (*hook)(int, void*); + void* param; + struct exit_handler* next; +}; +extern struct exit_handler* __exit_handler_stack; +#endif + /* TODO: These are not implemented in sortix libc yet. */ #if 0 long a64l(const char* s); diff --git a/libc/stdlib/atexit.cpp b/libc/stdlib/atexit.cpp new file mode 100644 index 00000000..90212d6b --- /dev/null +++ b/libc/stdlib/atexit.cpp @@ -0,0 +1,35 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2012, 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library 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. + + The Sortix C Library 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 the Sortix C Library. If not, see . + + stdlib/atexit.cpp + Hooks that are called upon process exit. + +*******************************************************************************/ + +#include + +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); +} diff --git a/libc/stdlib/exit.cpp b/libc/stdlib/exit.cpp index fed7fa57..a61b3dfe 100644 --- a/libc/stdlib/exit.cpp +++ b/libc/stdlib/exit.cpp @@ -26,11 +26,15 @@ #include #include -extern "C" void call_exit_handlers(int status); +extern "C" { struct exit_handler* __exit_handler_stack = NULL; } extern "C" void exit(int status) { - call_exit_handlers(status); + while ( __exit_handler_stack ) + { + __exit_handler_stack->hook(status, __exit_handler_stack->param); + __exit_handler_stack = __exit_handler_stack->next; + } dcloseall(); fcloseall(); _Exit(status); diff --git a/libc/stdlib/on_exit.cpp b/libc/stdlib/on_exit.cpp index 36b9cd6e..3904b8c3 100644 --- a/libc/stdlib/on_exit.cpp +++ b/libc/stdlib/on_exit.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2012. + Copyright(C) Jonas 'Sortie' Termansen 2012, 2013. This file is part of the Sortix C Library. @@ -18,45 +18,21 @@ along with the Sortix C Library. If not, see . stdlib/on_exit.cpp - Hooks that is called upon process exit. + Hooks that are 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; } + struct exit_handler* handler = + (struct exit_handler*) malloc(sizeof(struct exit_handler)); + if ( !handler ) + return -1; handler->hook = hook; handler->param = param; - handler->next = exit_handler_stack; - exit_handler_stack = handler; + 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; - } -}