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