/* Menes - C++ High-Level Utility Library * Copyright (C) 2004 Jay Freeman (saurik) */ /* * Redistribution and use in source and binary * forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the * above copyright notice, this list of conditions * and the following disclaimer. * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions * and the following disclaimer in the documentation * and/or other materials provided with the * distribution. * 3. The name of the author may not be used to endorse * or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include namespace { struct ExitRecord_ { ExitRecord_ *next_; void (*func_)(void *); void *arg_; void *dso_; } *atexits_; } extern "C" void *__dso_handle; extern "C" int __cxa_atexit(void (*func)(void *), void *arg, void *dso) { ExitRecord_ *record(reinterpret_cast(::malloc(sizeof(ExitRecord_)))); record->next_ = atexits_; record->func_ = func; record->arg_ = arg; record->dso_ = dso; atexits_ = record; return 0; } extern "C" void __cxa_finalize(void *dso) { ExitRecord_ **record(&atexits_); while ((*record) != NULL) if (dso != NULL && (*record)->dso_ != dso) record = &(*record)->next_; else { (*record)->func_((*record)->arg_); ExitRecord_ *previous(*record); *record = (*record)->next_; ::free(previous); } } namespace { struct AtExit_ { AtExit_() { atexit(&AtExit_::Exit); } static void Exit() { __cxa_finalize(__dso_handle); } } atexit_; };