1 /* -*-C-*- 2 3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 4 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 5 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts 6 Institute of Technology 7 8 This file is part of MIT/GNU Scheme. 9 10 MIT/GNU Scheme is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 2 of the License, or (at 13 your option) any later version. 14 15 MIT/GNU Scheme is distributed in the hope that it will be useful, but 16 WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with MIT/GNU Scheme; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 23 USA. 24 25 */ 26 27 /* Signal Handlers */ 28 29 #ifndef SCM_UXSIG_H 30 #define SCM_UXSIG_H 31 32 #ifndef HAVE_POSIX_SIGNALS 33 # ifdef HAVE_SIGHOLD 34 # define INSTALL_HANDLER UX_sigset 35 # define NEED_HANDLER_TRANSACTION 36 # define ENTER_HANDLER(signo) 37 # define ABORT_HANDLER(signo, handler) UX_sigrelse (signo) 38 # define EXIT_HANDLER(signo, handler) 39 # else 40 # define INSTALL_HANDLER UX_signal 41 # define NEED_HANDLER_TRANSACTION 42 # define ENTER_HANDLER(signo) UX_signal ((signo), SIG_IGN) 43 # define ABORT_HANDLER UX_signal 44 # define EXIT_HANDLER UX_signal 45 # endif 46 #endif 47 48 #if defined(CC_IS_NATIVE) && !defined(SIGNAL_HANDLERS_CAN_USE_SCHEME_STACK) 49 50 struct signal_instance 51 { 52 int signo; 53 SIGINFO_T info; 54 SIGCONTEXT_ARG_T * pscp; 55 }; 56 57 # define DEFUN_STD_HANDLER(name, statement) \ 58 \ 59 DEFUN_STD_HANDLER_ (name##_body, statement) \ 60 \ 61 void \ 62 name##_wrapper (void *context) \ 63 { \ 64 struct signal_instance *i = context; \ 65 (void) name##_body ((i->signo), (i->info), (i->pscp)); \ 66 } \ 67 \ 68 Tsignal_handler_result \ 69 name (int signo, SIGINFO_T info, SIGCONTEXT_ARG_T * pscp) \ 70 { \ 71 struct signal_instance i; \ 72 (i.signo) = signo; \ 73 (i.info) = info; \ 74 (i.pscp) = pscp; \ 75 within_c_stack ((&name##_wrapper), (&i)); \ 76 SIGNAL_HANDLER_RETURN (); \ 77 } 78 79 #else 80 81 # define DEFUN_STD_HANDLER DEFUN_STD_HANDLER_ 82 83 #endif /* CC_SUPPORT_P && !SIGNAL_HANDLERS_CAN_USE_SCHEME_STACK */ 84 85 #ifndef NEED_HANDLER_TRANSACTION 86 87 #define DEFUN_STD_HANDLER_(name, statement) \ 88 Tsignal_handler_result \ 89 name (int signo, \ 90 SIGINFO_T info, \ 91 SIGCONTEXT_ARG_T * pscp) \ 92 { \ 93 int STD_HANDLER_abortp; \ 94 DECLARE_SIGCONTEXT (scp, pscp); \ 95 record_signal_delivery (signo); \ 96 STD_HANDLER_abortp = (enter_interruption_extent ()); \ 97 statement; \ 98 if (STD_HANDLER_abortp) \ 99 exit_interruption_extent (); \ 100 SIGNAL_HANDLER_RETURN (); \ 101 } 102 103 #else /* NEED_HANDLER_TRANSACTION */ 104 105 struct handler_record 106 { 107 int signo; 108 Tsignal_handler handler; 109 }; 110 111 #define DEFUN_STD_HANDLER_(name, statement) \ 112 Tsignal_handler_result \ 113 name (int signo, \ 114 SIGINFO_T info, \ 115 SIGCONTEXT_ARG_T * pscp) \ 116 { \ 117 int STD_HANDLER_abortp; \ 118 DECLARE_SIGCONTEXT (scp, pscp); \ 119 ENTER_HANDLER (signo); \ 120 record_signal_delivery (signo); \ 121 STD_HANDLER_abortp = (enter_interruption_extent ()); \ 122 transaction_begin (); \ 123 { \ 124 struct handler_record * record = \ 125 (dstack_alloc (sizeof (struct handler_record))); \ 126 (record -> signo) = signo; \ 127 (record -> handler) = name; \ 128 transaction_record_action (tat_abort, ta_abort_handler, record); \ 129 } \ 130 statement; \ 131 if (STD_HANDLER_abortp) \ 132 { \ 133 transaction_abort (); \ 134 exit_interruption_extent (); \ 135 } \ 136 transaction_commit (); \ 137 EXIT_HANDLER (signo, name); \ 138 SIGNAL_HANDLER_RETURN (); \ 139 } 140 141 extern void ta_abort_handler (void *); 142 143 #endif /* NEED_HANDLER_TRANSACTION */ 144 145 #ifndef DEBUG_SIGNAL_DELIVERY 146 #define record_signal_delivery(signo) 147 #endif 148 149 #endif /* SCM_UXSIG_H */ 150