1*57718be8SEnji Cooper /* $NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ */ 2*57718be8SEnji Cooper 3*57718be8SEnji Cooper /*- 4*57718be8SEnji Cooper * Copyright (c) 2011 The NetBSD Foundation, Inc. 5*57718be8SEnji Cooper * All rights reserved. 6*57718be8SEnji Cooper * 7*57718be8SEnji Cooper * This code was contributed to The NetBSD Foundation by Jason R. Thorpe. 8*57718be8SEnji Cooper * 9*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 10*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 11*57718be8SEnji Cooper * are met: 12*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 13*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 14*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 15*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 16*57718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 17*57718be8SEnji Cooper * 18*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19*57718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20*57718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21*57718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22*57718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*57718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*57718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*57718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*57718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*57718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 29*57718be8SEnji Cooper */ 30*57718be8SEnji Cooper 31*57718be8SEnji Cooper #include <sys/cdefs.h> 32*57718be8SEnji Cooper __COPYRIGHT("@(#) Copyright (c) 2011\ 33*57718be8SEnji Cooper The NetBSD Foundation, inc. All rights reserved."); 34*57718be8SEnji Cooper __RCSID("$NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $"); 35*57718be8SEnji Cooper 36*57718be8SEnji Cooper #include <stdio.h> 37*57718be8SEnji Cooper #include <stdlib.h> 38*57718be8SEnji Cooper #include <signal.h> 39*57718be8SEnji Cooper #include <string.h> 40*57718be8SEnji Cooper #include <unistd.h> 41*57718be8SEnji Cooper 42*57718be8SEnji Cooper extern int __cxa_atexit(void (*func)(void *), void *, void *); 43*57718be8SEnji Cooper extern void __cxa_finalize(void *); 44*57718be8SEnji Cooper 45*57718be8SEnji Cooper static int dso_handle_1; 46*57718be8SEnji Cooper static int dso_handle_2; 47*57718be8SEnji Cooper static int dso_handle_3; 48*57718be8SEnji Cooper 49*57718be8SEnji Cooper static int arg_1; 50*57718be8SEnji Cooper static int arg_2; 51*57718be8SEnji Cooper static int arg_3; 52*57718be8SEnji Cooper 53*57718be8SEnji Cooper static int exiting_state; 54*57718be8SEnji Cooper 55*57718be8SEnji Cooper #define ASSERT(expr) \ 56*57718be8SEnji Cooper do { \ 57*57718be8SEnji Cooper if ((expr) == 0) { \ 58*57718be8SEnji Cooper write(STDERR_FILENO, __func__, strlen(__func__)); \ 59*57718be8SEnji Cooper write(STDERR_FILENO, ": ", 2); \ 60*57718be8SEnji Cooper write(STDERR_FILENO, __STRING(expr), \ 61*57718be8SEnji Cooper strlen(__STRING(expr))); \ 62*57718be8SEnji Cooper write(STDERR_FILENO, "\n", 1); \ 63*57718be8SEnji Cooper my_abort(); \ 64*57718be8SEnji Cooper } \ 65*57718be8SEnji Cooper } while (/*CONSTCOND*/0) 66*57718be8SEnji Cooper 67*57718be8SEnji Cooper #define SUCCESS() \ 68*57718be8SEnji Cooper do { \ 69*57718be8SEnji Cooper write(STDOUT_FILENO, __func__, strlen(__func__)); \ 70*57718be8SEnji Cooper write(STDOUT_FILENO, "\n", 1); \ 71*57718be8SEnji Cooper } while (/*CONSTCOND*/0) 72*57718be8SEnji Cooper 73*57718be8SEnji Cooper static void 74*57718be8SEnji Cooper my_abort(void) 75*57718be8SEnji Cooper { 76*57718be8SEnji Cooper 77*57718be8SEnji Cooper kill(getpid(), SIGABRT); 78*57718be8SEnji Cooper /* NOTREACHED */ 79*57718be8SEnji Cooper } 80*57718be8SEnji Cooper 81*57718be8SEnji Cooper static void 82*57718be8SEnji Cooper cxa_handler_5(void *arg) 83*57718be8SEnji Cooper { 84*57718be8SEnji Cooper static int cxa_handler_5_called; 85*57718be8SEnji Cooper 86*57718be8SEnji Cooper ASSERT(arg == (void *)&arg_1); 87*57718be8SEnji Cooper ASSERT(cxa_handler_5_called == 0); 88*57718be8SEnji Cooper ASSERT(exiting_state == 5); 89*57718be8SEnji Cooper 90*57718be8SEnji Cooper exiting_state--; 91*57718be8SEnji Cooper cxa_handler_5_called = 1; 92*57718be8SEnji Cooper SUCCESS(); 93*57718be8SEnji Cooper } 94*57718be8SEnji Cooper 95*57718be8SEnji Cooper static void 96*57718be8SEnji Cooper cxa_handler_4(void *arg) 97*57718be8SEnji Cooper { 98*57718be8SEnji Cooper static int cxa_handler_4_called; 99*57718be8SEnji Cooper 100*57718be8SEnji Cooper ASSERT(arg == (void *)&arg_1); 101*57718be8SEnji Cooper ASSERT(cxa_handler_4_called == 0); 102*57718be8SEnji Cooper ASSERT(exiting_state == 4); 103*57718be8SEnji Cooper 104*57718be8SEnji Cooper exiting_state--; 105*57718be8SEnji Cooper cxa_handler_4_called = 1; 106*57718be8SEnji Cooper SUCCESS(); 107*57718be8SEnji Cooper } 108*57718be8SEnji Cooper 109*57718be8SEnji Cooper static void 110*57718be8SEnji Cooper cxa_handler_3(void *arg) 111*57718be8SEnji Cooper { 112*57718be8SEnji Cooper static int cxa_handler_3_called; 113*57718be8SEnji Cooper 114*57718be8SEnji Cooper ASSERT(arg == (void *)&arg_2); 115*57718be8SEnji Cooper ASSERT(cxa_handler_3_called == 0); 116*57718be8SEnji Cooper ASSERT(exiting_state == 3); 117*57718be8SEnji Cooper 118*57718be8SEnji Cooper exiting_state--; 119*57718be8SEnji Cooper cxa_handler_3_called = 1; 120*57718be8SEnji Cooper SUCCESS(); 121*57718be8SEnji Cooper } 122*57718be8SEnji Cooper 123*57718be8SEnji Cooper static void 124*57718be8SEnji Cooper cxa_handler_2(void *arg) 125*57718be8SEnji Cooper { 126*57718be8SEnji Cooper static int cxa_handler_2_called; 127*57718be8SEnji Cooper 128*57718be8SEnji Cooper ASSERT(arg == (void *)&arg_3); 129*57718be8SEnji Cooper ASSERT(cxa_handler_2_called == 0); 130*57718be8SEnji Cooper ASSERT(exiting_state == 2); 131*57718be8SEnji Cooper 132*57718be8SEnji Cooper exiting_state--; 133*57718be8SEnji Cooper cxa_handler_2_called = 1; 134*57718be8SEnji Cooper SUCCESS(); 135*57718be8SEnji Cooper } 136*57718be8SEnji Cooper 137*57718be8SEnji Cooper static void 138*57718be8SEnji Cooper normal_handler_1(void) 139*57718be8SEnji Cooper { 140*57718be8SEnji Cooper static int normal_handler_1_called; 141*57718be8SEnji Cooper 142*57718be8SEnji Cooper ASSERT(normal_handler_1_called == 0); 143*57718be8SEnji Cooper ASSERT(exiting_state == 1); 144*57718be8SEnji Cooper 145*57718be8SEnji Cooper exiting_state--; 146*57718be8SEnji Cooper normal_handler_1_called = 1; 147*57718be8SEnji Cooper SUCCESS(); 148*57718be8SEnji Cooper } 149*57718be8SEnji Cooper 150*57718be8SEnji Cooper static void 151*57718be8SEnji Cooper normal_handler_0(void) 152*57718be8SEnji Cooper { 153*57718be8SEnji Cooper static int normal_handler_0_called; 154*57718be8SEnji Cooper 155*57718be8SEnji Cooper ASSERT(normal_handler_0_called == 0); 156*57718be8SEnji Cooper ASSERT(exiting_state == 0); 157*57718be8SEnji Cooper 158*57718be8SEnji Cooper normal_handler_0_called = 1; 159*57718be8SEnji Cooper SUCCESS(); 160*57718be8SEnji Cooper } 161*57718be8SEnji Cooper 162*57718be8SEnji Cooper int 163*57718be8SEnji Cooper main(int argc, char *argv[]) 164*57718be8SEnji Cooper { 165*57718be8SEnji Cooper 166*57718be8SEnji Cooper exiting_state = 5; 167*57718be8SEnji Cooper 168*57718be8SEnji Cooper ASSERT(0 == atexit(normal_handler_0)); 169*57718be8SEnji Cooper ASSERT(0 == atexit(normal_handler_1)); 170*57718be8SEnji Cooper ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); 171*57718be8SEnji Cooper ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); 172*57718be8SEnji Cooper ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); 173*57718be8SEnji Cooper ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3)); 174*57718be8SEnji Cooper 175*57718be8SEnji Cooper __cxa_finalize(&dso_handle_1); 176*57718be8SEnji Cooper __cxa_finalize(&dso_handle_2); 177*57718be8SEnji Cooper exit(0); 178*57718be8SEnji Cooper } 179