----------------------------------------------------------------------- -- Howard Eng 6/94-- -- Unixpros, Inc. -- -- -- -- This package defines data types and functions required for signal -- -- handling. -- -- -- -- Signal handling uses a combination of the Ada Interrupt facility -- -- and DCE Threads concepts. Specifically, the signal delivery and -- -- processing mechanisms are similar to DCE, but the catching of -- -- signals is all Ada. For example, the bindings allow applications -- -- to catch asynchronous signals using "sigwait()". Synchronous -- -- signals are caught by using the wrappered "sigaction()" that DCE -- -- provides. -- -- -- -- For this implementation interrupts are caught by installing -- -- Ada handlers for each signal. The handler is installed by a call -- -- to "sigwait()" or through the wrappered "sigaction()". Interrupt -- -- processing/delivery is made through an interrupt entry that the -- -- installed handler will make. The interrupt entry delivers the -- -- signal using the DCE facilities. -- -- -- ----------------------------------------------------------------------- with SYSTEM; with CMA_TYPES; with INTERRUPT_MANAGER; package DCE_ADA_SIGNAL is use INTERRUPT_MANAGER; function ADA_THD_INSTALL_HANDLER( SIG : CMA_TYPES.C_INTEGER ) return CMA_TYPES.C_INTEGER; pragma EXPORT( C, ADA_THD_INSTALL_HANDLER ); function ADA_THD_REMOVE_HANDLER( SIG : CMA_TYPES.C_INTEGER ) return CMA_TYPES.C_INTEGER; pragma EXPORT( C, ADA_THD_REMOVE_HANDLER ); procedure ADA_THD_INIT_SIGNAL; pragma EXPORT( C, ADA_THD_INIT_SIGNAL ); private NSIG : constant CMA_TYPES.C_INTEGER := 32; SIGHUP_N : constant SIGNAL_NUMBER := 1; SIGINT_N : constant SIGNAL_NUMBER := 2; SIGQUIT_N : constant SIGNAL_NUMBER := 3; SIGILL_N : constant SIGNAL_NUMBER := 4; SIGTRAP_N : constant SIGNAL_NUMBER := 5; SIGIOT_N : constant SIGNAL_NUMBER := 6; SIGEMT_N : constant SIGNAL_NUMBER := 7; SIGFPE_N : constant SIGNAL_NUMBER := 8; SIGKILL_N : constant SIGNAL_NUMBER := 9; SIGBUS_N : constant SIGNAL_NUMBER := 10; SIGSEGV_N : constant SIGNAL_NUMBER := 11; SIGSYS_N : constant SIGNAL_NUMBER := 12; SIGPIPE_N : constant SIGNAL_NUMBER := 13; SIGALRM_N : constant SIGNAL_NUMBER := 14; SIGTERM_N : constant SIGNAL_NUMBER := 15; SIGUSR1_N : constant SIGNAL_NUMBER := 16; SIGUSR2_N : constant SIGNAL_NUMBER := 17; SIGCHLD_N : constant SIGNAL_NUMBER := 18; SIGPWR_N : constant SIGNAL_NUMBER := 19; SIGVTALRM_N : constant SIGNAL_NUMBER := 20; SIGPROF_N : constant SIGNAL_NUMBER := 21; SIGIO_N : constant SIGNAL_NUMBER := 22; SIGWINDOW_N : constant SIGNAL_NUMBER := 23; SIGSTOP_N : constant SIGNAL_NUMBER := 24; SIGTSTP_N : constant SIGNAL_NUMBER := 25; SIGCONT_N : constant SIGNAL_NUMBER := 26; SIGTTIN_N : constant SIGNAL_NUMBER := 27; SIGTTOU_N : constant SIGNAL_NUMBER := 28; SIGURG_N : constant SIGNAL_NUMBER := 29; SIGLOST_N : constant SIGNAL_NUMBER := 30; SIGRESERVE_N : constant SIGNAL_NUMBER := 31; SIGDIL_N : constant SIGNAL_NUMBER := 32; SIGHUP : constant SYSTEM.ADDRESS := SIGNAL( SIGHUP_N ); SIGINT : constant SYSTEM.ADDRESS := SIGNAL( SIGINT_N ); SIGQUIT : constant SYSTEM.ADDRESS := SIGNAL( SIGQUIT_N ); SIGILL : constant SYSTEM.ADDRESS := SIGNAL( SIGILL_N ); SIGTRAP : constant SYSTEM.ADDRESS := SIGNAL( SIGTRAP_N ); SIGIOT : constant SYSTEM.ADDRESS := SIGNAL( SIGIOT_N ); SIGEMT : constant SYSTEM.ADDRESS := SIGNAL( SIGEMT_N ); SIGFPE : constant SYSTEM.ADDRESS := SIGNAL( SIGFPE_N ); SIGKILL : constant SYSTEM.ADDRESS := SIGNAL( SIGKILL_N ); SIGBUS : constant SYSTEM.ADDRESS := SIGNAL( SIGBUS_N ); SIGSEGV : constant SYSTEM.ADDRESS := SIGNAL( SIGSEGV_N ); SIGSYS : constant SYSTEM.ADDRESS := SIGNAL( SIGSYS_N ); SIGPIPE : constant SYSTEM.ADDRESS := SIGNAL( SIGPIPE_N ); SIGALRM : constant SYSTEM.ADDRESS := SIGNAL( SIGALRM_N ); SIGTERM : constant SYSTEM.ADDRESS := SIGNAL( SIGTERM_N ); SIGUSR1 : constant SYSTEM.ADDRESS := SIGNAL( SIGUSR1_N ); SIGUSR2 : constant SYSTEM.ADDRESS := SIGNAL( SIGUSR2_N ); SIGCHLD : constant SYSTEM.ADDRESS := SIGNAL( SIGCHLD_N ); SIGPWR : constant SYSTEM.ADDRESS := SIGNAL( SIGPWR_N ); SIGVTALRM : constant SYSTEM.ADDRESS := SIGNAL( SIGVTALRM_N ); SIGPROF : constant SYSTEM.ADDRESS := SIGNAL( SIGPROF_N ); SIGIO : constant SYSTEM.ADDRESS := SIGNAL( SIGIO_N ); SIGWINDOW : constant SYSTEM.ADDRESS := SIGNAL( SIGWINDOW_N ); SIGSTOP : constant SYSTEM.ADDRESS := SIGNAL( SIGSTOP_N ); SIGTSTP : constant SYSTEM.ADDRESS := SIGNAL( SIGTSTP_N ); SIGCONT : constant SYSTEM.ADDRESS := SIGNAL( SIGCONT_N ); SIGTTIN : constant SYSTEM.ADDRESS := SIGNAL( SIGTTIN_N ); SIGTTOU : constant SYSTEM.ADDRESS := SIGNAL( SIGTTOU_N ); SIGURG : constant SYSTEM.ADDRESS := SIGNAL( SIGURG_N ); SIGLOST : constant SYSTEM.ADDRESS := SIGNAL( SIGLOST_N ); SIGRESERVE : constant SYSTEM.ADDRESS := SIGNAL( SIGRESERVE_N ); SIGDIL : constant SYSTEM.ADDRESS := SIGNAL( SIGDIL_N ); -- -- The interrupt task that will process/deliver the signal. Entries -- with the "TCB" parameter are the "synchronous" signals. -- task type ADA_THD_INTERRUPT_TASK_T is entry SIGHUP_E; entry SIGINT_E; entry SIGQUIT_E; entry SIGILL_E( TCB : in SYSTEM.ADDRESS ); entry SIGTRAP_E; entry SIGIOT_E( TCB : in SYSTEM.ADDRESS ); entry SIGEMT_E( TCB : in SYSTEM.ADDRESS ); entry SIGFPE_E( TCB : in SYSTEM.ADDRESS ); entry SIGKILL_E; entry SIGBUS_E( TCB : in SYSTEM.ADDRESS ); entry SIGSEGV_E( TCB : in SYSTEM.ADDRESS ); entry SIGSYS_E( TCB : in SYSTEM.ADDRESS ); entry SIGPIPE_E( TCB : in SYSTEM.ADDRESS ); entry SIGALRM_E; entry SIGTERM_E; entry SIGUSR1_E; entry SIGUSR2_E; entry SIGCHLD_E; entry SIGPWR_E; entry SIGVTALRM_E; entry SIGPROF_E; entry SIGIO_E; entry SIGWINDOW_E; entry SIGSTOP_E; entry SIGTSTP_E; entry SIGCONT_E; entry SIGTTIN_E; entry SIGTTOU_E; entry SIGURG_E; entry SIGLOST_E; entry SIGRESERVE_E; entry SIGDIL_E; entry INSTALL_HANDLER( SIG : CMA_TYPES.C_INTEGER ); entry REMOVE_HANDLER( SIG : CMA_TYPES.C_INTEGER ); for SIGHUP_E use at SIGHUP; for SIGINT_E use at SIGINT; for SIGQUIT_E use at SIGQUIT; for SIGILL_E use at SIGILL; for SIGTRAP_E use at SIGTRAP; for SIGIOT_E use at SIGIOT; for SIGEMT_E use at SIGEMT; for SIGFPE_E use at SIGFPE; for SIGKILL_E use at SIGKILL; for SIGBUS_E use at SIGBUS; for SIGSEGV_E use at SIGSEGV; for SIGSYS_E use at SIGSYS; for SIGPIPE_E use at SIGPIPE; for SIGALRM_E use at SIGALRM; for SIGTERM_E use at SIGTERM; for SIGUSR1_E use at SIGUSR1; for SIGUSR2_E use at SIGUSR2; for SIGCHLD_E use at SIGCHLD; for SIGPWR_E use at SIGPWR; for SIGVTALRM_E use at SIGVTALRM; for SIGPROF_E use at SIGPROF; for SIGIO_E use at SIGIO; for SIGWINDOW_E use at SIGWINDOW; for SIGSTOP_E use at SIGSTOP; for SIGTSTP_E use at SIGTSTP; for SIGCONT_E use at SIGCONT; for SIGTTIN_E use at SIGTTIN; for SIGTTOU_E use at SIGTTOU; for SIGURG_E use at SIGURG; for SIGLOST_E use at SIGLOST; for SIGRESERVE_E use at SIGRESERVE; for SIGDIL_E use at SIGDIL; end; for ADA_THD_INTERRUPT_TASK_T'STORAGE_SIZE use 8192; -- -- Declarations for each of the signal handler procedures. Alsys -- claims that a single handler can be registered for more than -- one signal and the runtime will pass in the signal number when -- it is invoked. That didn't seem to work. The input parameter was -- always NULL. Thats why there's a separate handler for each signal -- procedure SIGHUP_P; procedure SIGINT_P; procedure SIGQUIT_P; procedure SIGILL_P; procedure SIGTRAP_P; procedure SIGIOT_P; procedure SIGEMT_P; procedure SIGFPE_P; procedure SIGKILL_P; procedure SIGBUS_P; procedure SIGSEGV_P; procedure SIGSYS_P; procedure SIGPIPE_P; procedure SIGALRM_P; procedure SIGTERM_P; procedure SIGUSR1_P; procedure SIGUSR2_P; procedure SIGCHLD_P; procedure SIGPWR_P; procedure SIGVTALRM_P; procedure SIGPROF_P; procedure SIGIO_P; procedure SIGWINDOW_P; procedure SIGSTOP_P; procedure SIGTSTP_P; procedure SIGCONT_P; procedure SIGTTIN_P; procedure SIGTTOU_P; procedure SIGURG_P; procedure SIGLOST_P; procedure SIGRESERVE_P; procedure SIGDIL_P; type SIG_VEC_T is record SIGNAL : SYSTEM.ADDRESS; HANDLER : SYSTEM.ADDRESS; INSTALLED : BOOLEAN; end record; type SIG_TBL_T is array ( CMA_TYPES.C_INTEGER range 1..NSIG ) of SIG_VEC_T; -- -- This table is used to install signal handlers on an as needed basis. -- Note that the table is ordered in signal number order. -- SIG_TABLE : SIG_TBL_T := ( ( SIGHUP, SIGHUP_P'ADDRESS, FALSE ), ( SIGINT, SIGINT_P'ADDRESS, FALSE ), ( SIGQUIT, SIGQUIT_P'ADDRESS, FALSE ), ( SIGILL, SIGILL_P'ADDRESS, FALSE ), ( SIGTRAP, SIGTRAP_P'ADDRESS, FALSE ), ( SIGIOT, SIGIOT_P'ADDRESS, FALSE ), ( SIGEMT, SIGEMT_P'ADDRESS, FALSE ), ( SIGFPE, SIGFPE_P'ADDRESS, FALSE ), ( SIGKILL, SIGKILL_P'ADDRESS, FALSE ), ( SIGBUS, SIGBUS_P'ADDRESS, FALSE ), ( SIGSEGV, SIGSEGV_P'ADDRESS, FALSE ), ( SIGSYS, SIGSYS_P'ADDRESS, FALSE ), ( SIGPIPE, SIGPIPE_P'ADDRESS, FALSE ), ( SIGALRM, SIGALRM_P'ADDRESS, FALSE ), ( SIGTERM, SIGTERM_P'ADDRESS, FALSE ), ( SIGUSR1, SIGUSR1_P'ADDRESS, FALSE ), ( SIGUSR2, SIGUSR2_P'ADDRESS, FALSE ), ( SIGCHLD, SIGCHLD_P'ADDRESS, FALSE ), ( SIGPWR, SIGPWR_P'ADDRESS, FALSE ), ( SIGVTALRM, SIGVTALRM_P'ADDRESS, FALSE ), ( SIGPROF, SIGPROF_P'ADDRESS, FALSE ), ( SIGIO, SIGIO_P'ADDRESS, FALSE ), ( SIGWINDOW, SIGWINDOW_P'ADDRESS, FALSE ), ( SIGSTOP, SIGSTOP_P'ADDRESS, FALSE ), ( SIGTSTP, SIGTSTP_P'ADDRESS, FALSE ), ( SIGCONT, SIGCONT_P'ADDRESS, FALSE ), ( SIGTTIN, SIGTTIN_P'ADDRESS, FALSE ), ( SIGTTOU, SIGTTOU_P'ADDRESS, FALSE ), ( SIGURG, SIGURG_P'ADDRESS, FALSE ), ( SIGLOST, SIGLOST_P'ADDRESS, FALSE ), ( SIGRESERVE, SIGRESERVE_P'ADDRESS, FALSE ), ( SIGDIL, SIGDIL_P'ADDRESS, FALSE ) ); INTERRUPT_TASK : ADA_THD_INTERRUPT_TASK_T; end DCE_ADA_SIGNAL;