1 /* 2 * Copyright (C) 2025 Kyle Evans <kevans@FreeBSD.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 * 6 */ 7 8 #include <unistd.h> 9 10 static int exit_code = -1; 11 static bool fatal_atexit; 12 13 extern "C" { 14 void set_fatal_atexit(bool); 15 void set_exit_code(int); 16 } 17 18 void 19 set_fatal_atexit(bool fexit) 20 { 21 fatal_atexit = fexit; 22 } 23 24 void 25 set_exit_code(int code) 26 { 27 exit_code = code; 28 } 29 30 struct other_object { 31 ~other_object() { 32 33 /* 34 * In previous versions of our __cxa_atexit handling, we would 35 * never actually execute this handler because it's added during 36 * ~object() below; __cxa_finalize would never revisit it. We 37 * will allow the caller to configure us to exit with a certain 38 * exit code so that it can run us twice: once to ensure we 39 * don't crash at the end, and again to make sure the handler 40 * actually ran. 41 */ 42 if (exit_code != -1) 43 _exit(exit_code); 44 } 45 }; 46 47 void 48 create_staticobj() 49 { 50 static other_object obj; 51 } 52 53 struct object { 54 ~object() { 55 /* 56 * If we're doing the fatal_atexit behavior (i.e., create an 57 * object that will add its own dtor for __cxa_finalize), then 58 * we don't exit here. 59 */ 60 if (fatal_atexit) 61 create_staticobj(); 62 else if (exit_code != -1) 63 _exit(exit_code); 64 } 65 }; 66 67 static object obj; 68